2011-03-17 54 views
12

我一直在通过Haskell monoids and their uses,这让我对monoids的基础知识有了很好的理解。其中一个在博客中介绍的东西是任何幺半群,它就像下面的用法:在Haskell中使用Maybe编写Maximum Monoid

foldMap (Any . (== 1)) tree 
foldMap (All . (> 1)) [1,2,3] 

与此类似,我一直在努力构建一个最大的独异,并拿出以下:

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

instance Ord a => Monoid (Maximum a) where 
     mempty = Maximum Nothing 
     [email protected](Maximum (Just x)) `mappend` Maximum Nothing = m 
     Maximum Nothing `mappend` y = y 
     [email protected](Maximum (Just x)) `mappend` [email protected](Maximum (Just y)) 
      | x > y = m 
      | otherwise = n 

我可以构建针对特定类型的最大幺 - 说民例如,很容易,但希望它是什么(用的是什么是奥德的实例明显的要求)是有用的。

在这一点上我的代码编译,但就是这样。如果我尝试运行它,我得到这个:

> 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) 

我不知道这是因为我打电话错了,还是因为我的幺不正确,或两者兼而有之。我很感谢任何有关我出错的指导(包括逻辑错误和非惯用Haskell用法,因为我对这门语言很陌生)。

- 编辑 -

保罗·约翰逊,在下面留言,提示可能留下了。我的第一次尝试看起来是这样的:

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

instance Ord a => Monoid (Minimum a) where 
     mempty = ?? 
     [email protected](Minimum x) `mappend` [email protected](Minimum y) 
      | x < y  = m 
      | otherwise = n 

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

+0

我看看它是如何工作的,但为什么会有“也许”内的最高类型?如果你只是说“最大a”,那么它简化了你的实例。 “也许a”只要是“a”就是Ord的一个实例,所以你可以只说“最大(也许是整数)”,它会做正确的事情。 – 2011-03-18 09:44:52

+0

@Paul Johnson我看到你离开Maybe的原因,但我不知道如何表达。我将代码添加到了上面的问题中,以便它更具可读性。 – 2011-03-18 10:53:26

+2

啊,我看到你的问题。如果你添加了“Bounded”作为约束,那么你可以让mempty返回Minimum的下限和Maximum的上限。否则你是正确的;对于mempty来说没有正确的事情。这意味着这不是一个monoid。 – 2011-03-18 22:00:26

回答

12

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

> foldMap (Maximum . Just) [1,2,3] 
Maximum {getMaximum = Just 3} 
+0

现在你指出了,这似乎很明显:)谢谢你的答案! – 2011-03-17 21:17:22

+1

ala'最大foldMap只需[1,2,3] =只有3 - 给定最大的正确Newtype实例。从这个包: http://hackage.haskell.org/package/newtype – 2011-03-18 14:29:05