在Haskell中使用Maybe写一个最大Monoid

luk*_*all 12 haskell monoids

我一直在经历Haskell幺半群及其用途,这让我对幺半群的基本知识有了很好的理解.博客文章中介绍的一件事是Any monoid,它的用法如下:

foldMap (Any . (== 1)) tree
foldMap (All . (> 1)) [1,2,3]
Run Code Online (Sandbox Code Playgroud)

在类似的情况下,我一直在尝试构建一个最大的幺半群,并提出以下内容:

newtype Maximum a = Maximum { getMaximum :: Maybe a }
        deriving (Eq, Ord, Read, Show)

instance Ord a => Monoid (Maximum a) where
        mempty = Maximum Nothing
        m@(Maximum (Just x)) `mappend` Maximum Nothing = m
        Maximum Nothing `mappend` y = y
        m@(Maximum (Just x)) `mappend` n@(Maximum (Just y))
          | x > y = m
          | otherwise = n
Run Code Online (Sandbox Code Playgroud)

我可以为特定类型构造一个最大幺半群 - 例如Num,非常容易,但希望它对任何东西都有用(明显要求任何东西都是Ord的一个实例).

此时我的代码编译,但就是这样.如果我尝试运行它,我得到这个:

> foldMap (Just) [1,2,3]

<interactive>:1:20:
    Ambiguous type variable `a' in the constraints:
      `Num a' arising from the literal `3' at <interactive>:1:20
      `Monoid a' arising from a use of `foldMap' at <interactive>:1:0-21
    Probable fix: add a type signature that fixes these type variable(s)
Run Code Online (Sandbox Code Playgroud)

我不确定这是因为我说错了,还是因为我的幺半群不正确,或者两者兼而有之.我很欣赏任何关于我出错的指导(在逻辑错误和非惯用的Haskell使用方面,因为我对语言很新).

- 编辑 -

保罗约翰逊在下面的评论中建议离开梅.我的第一次尝试看起来像这样:

newtype Minimum a = Minimum { getMinimum :: a }
        deriving (Eq, Ord, Read, Show)

instance Ord a => Monoid (Minimum a) where
        mempty = ??
        m@(Minimum x) `mappend` n@(Minimum y)
          | x < y     = m
          | otherwise = n
Run Code Online (Sandbox Code Playgroud)

但我不清楚如何表达mempty而不知道应该是什么样的mempty值.我怎么能概括这个?

int*_*jay 12

传递给函数的函数foldMap需要返回一个monoid,在这种情况下类型为Maximum a:

> foldMap (Maximum . Just) [1,2,3]
Maximum {getMaximum = Just 3}
Run Code Online (Sandbox Code Playgroud)

  • ala'最大foldMap只是[1,2,3] =只是3 - 给出了最大的Newtype实例.从这个包:http://hackage.haskell.org/package/newtype (2认同)