在Haskell中使用Maybe编写Maximum Monoid [英] Write a Maximum Monoid using Maybe in Haskell

查看:122
本文介绍了在Haskell中使用Maybe编写Maximum Monoid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在浏览 Haskell monoids及其他使用,这让我对monoids的基础知识有了很好的理解。在博客文章中引入的一个东西是Any monoid,它的用法如下:
$ b $ pre $ foldMap(Any。( == 1))tree
foldMap(All。(> 1))[1,2,3]

以类似的方式,我一直在试图构建一个最大monoid,并且提出了以下内容:

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

实例Ord a => Monoid(最大a)其中
mempty =最大值不变
m @(最大值(只是x))`mappend`最大值无= m
最大值无`mappend` y = y
m @ (最大(只是x))`mappend` n @(最大(只是y))
| x> y = m
|否则= n

我可以为一个特定类型构造一个最大monoid,例如Num,很容易,但希望它对任何东西都有用(显然要求任何东西都是Ord的一个实例)。



在这一点上,我的代码编译完成了,但这是关于它的。如果我尝试运行它,我会得到:

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

< interactive>:1:20:
约束中含糊不清的类型变量'a':
`在< interactive>:1:20
由于在< interactive> 1:0-21处使用`foldMap'而产生的monoid a'
可能的修复:添加一个修复这些类型变量的类型签名

我不确定这是否是因为我称它错了,或者因为我的monoid不正确,或者两者都是。我会很感激任何关于我出错的指导(无论是在逻辑错误还是非惯用的Haskell使用方面,因为我对这门语言都很陌生)。

- 编辑 -



Paul Johnson在下面的评论中建议离开Maybe。我的第一次尝试如下所示:

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

实例Ord a => Monoid(最小a)其中
mempty = ??
m @(最小x)`mappend` n @(最小y)
| x < y = m
|否则= n

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

解决方案

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

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


I've been going through Haskell monoids and their uses, which has given me a fairly good understanding of the basics of monoids. One of the things introduced in the blog post is the Any monoid, and it's usage like the following:

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

In a similar vein, I've been trying to construct a Maximum monoid and have come up with the following:

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

I could construct a Maximum monoid for a specific type - say Num for example, quite easily, but want it to be useful for anything (with the obvious requirement that the anything is an instance of Ord).

At this point my code compiles, but that's about it. If I try to run it I get this:

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

I'm not sure if this is because I'm calling it wrong, or because my monoid is incorrect, or both. I'd appreciate any guidance on where I'm going wrong (both in terms of logic errors and non-idiomatic Haskell usage, as I'm very new to the language).

-- EDIT --

Paul Johnson, in a comment below, suggested leaving Maybe out. My first attempt looks like this:

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

but I'm unclear how to express mempty without knowing what the mempty value of a should be. How could I generalise this?

解决方案

The function passed to foldMap needs to return a monoid, in this case of type Maximum a:

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

这篇关于在Haskell中使用Maybe编写Maximum Monoid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆