感谢 network-api-support,我刚刚发现了 Endo 类型包,我发现需要能够将 Maybe 值放入 Endo 中。结果我写了一个名为 MaybeEndo 的函数。这是使用它的示例:
setProxy :: Proxy -> RequestTransformer
setProxy (Proxy pHost pPort) = Endo $ addProxy pHost pPort
maybeEndo :: (a -> Endo b) -> Maybe a -> Endo b
maybeEndo _ Nothing = Endo id
maybeEndo f (Just v) = f v
setPotentialProxy :: Maybe Proxy -> RequestTransformer
setPotentialProxy = maybeEndo setProxy
令我印象深刻的是,这似乎应该封装到某种类型的模式中。
最佳答案
您已经找到了也许 (Endo id)
。但Endo
是Monoid
的一个实例,而Endo id
是它的中性元素mempty
。所以你也可以写得更笼统
maybeMonoid :: Monoid b => (a -> b) -> Maybe a -> b
maybeMonoid = maybe mempty
这已经是很惯用的了(当你用谷歌搜索“maybe mempty”
时会出现大量的点击)。您可以通过使用 Data.Foldable 中的函数变得更加通用:
foldMap :: (Foldable t, Monoid b) => (a -> b) -> t a -> b
所以有了这个,你可以写
setPotentialProxy :: Maybe Proxy -> RequestTransformer
setPotentialProxy = foldMap setProxy
(但请确保保留类型签名,否则稍后在阅读代码时会花费太多时间来弄清楚它:-))。
关于Haskell:更好的写作方式也许是远藤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26560818/