【问题标题】:Haskell: Better way of writing Maybe Endo?Haskell:更好的写作方式可能是 Endo?
【发布时间】:2014-10-25 09:03:22
【问题描述】:

感谢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

让我印象深刻的是,这似乎应该已经封装到某种类型的模式中了。

【问题讨论】:

    标签: haskell maybe monoids


    【解决方案1】:

    您已经找到maybe (Endo id)。但是EndoMonoid 的一个实例,Endo id 是它的中性元素mempty。所以你也可以写得更笼统

    maybeMonoid :: Monoid b => (a -> b) -> Maybe a -> b
    maybeMonoid = maybe mempty
    

    这已经很惯用了(当您在 Google 上搜索 "maybe mempty" 时会获得大量点击)。使用Data.Foldable 中的函数可以更通用:

    foldMap :: (Foldable t, Monoid b) => (a -> b) -> t a -> b
    

    这样,你就可以写了

    setPotentialProxy :: Maybe Proxy -> RequestTransformer
    setPotentialProxy = foldMap setProxy
    

    (但请确保您留下类型签名,否则您将在稍后阅读代码时花费太多时间来弄清楚它:-))。

    【讨论】:

    • 它有一个名字:foldMap!太好了,这正是我想要的。很好的答案!
    【解决方案2】:

    当我写这个问题时,我想到了一个解决方案:

    maybeEndo :: (a -> Endo b) -> Maybe a -> Endo b
    maybeEndo = maybe (Endo id)
    

    这意味着 setPotentialProxy 可能只是:

    setPotentialProxy :: Maybe Proxy -> RequestTransformer
    setPotentialProxy = maybe (Endo id) setProxy
    

    但是,我仍然决定发布这个问题,因为也许有一种更自然的方式来处理这种情况。也许它会帮助其他人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多