模式匹配中的Monoid mempty [英] Monoid mempty in pattern matching

查看:164
本文介绍了模式匹配中的Monoid mempty的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着编写一个类似于 Prelude 中广义的最大函数。我的第一个naiv方法看起来像这样:

maximum'::(F.Foldable a,Ord b)=> a b - >也许b

最大'mempty = Nothing

最大'xs = Just $ F.foldl1 max xs



然而,当我测试它时总会返回 Nothing 不管输入如何:

>最大'[1,2,3]

> Nothing



现在我想知道是否有可能获得Monoid类型实例的空值。我写的一个测试函数可以正常工作:

getMempty ::(Monoid a)=> a - > a


getMempty _ = mempty



> getMempty [1,2,3]

> []



我已经看到了这两个问题,但我没有弄清楚答案如何解决我的问题:

在Haskell中使用Maybe编写最大Monoid

空集上的Haskell模式匹配



如何重写最大值函数以使其正常工作?
CA McCann在他的评论中指出,你不能在值上模式匹配,只有模式。



方程最大值'mempty = Nothing 实际上等价于方程最大值'x = Nothing 。参数被绑定到一个名字上,返回 Nothing



这是一种让代码有效的方法: (ab),幺半群(ab))=>(b)等式(ab) a b - >也许b
最大'xs
| xs == mempty = Nothing
|否则=只需$ F.foldl1 max xs

即。您可以将 xs mempty 进行比较。请注意,我们需要一个 Monoid 约束来获得值 mempty :: ab Eq 约束,以便能够进行比较。

另一个更优雅的解决方案是使用fold来区分在空的和非空的情况之间:

 最大''::(F.Foldable a,Ord b)=> a b  - >也许b 
最大''xs = F.foldl max'Nothing xs
where max'Nothing x = Just x
max'(Just y)x = Just $ max xy


I tried to write a generalized maximum function similar to the one in Prelude. My first naiv approach looked like this:
maximum' :: (F.Foldable a, Ord b) => a b -> Maybe b
maximum' mempty = Nothing
maximum' xs = Just $ F.foldl1 max xs

However, when I test it it always returns Nothing regardless of the input:
> maximum' [1,2,3]
> Nothing

Now I wonder whether it's possible to obtain the empty value of a Monoid type instance. A test function I wrote works correctly:
getMempty :: (Monoid a) => a -> a
getMempty _ = mempty

> getMempty [1,2,3]
> []

I had already a look at these two questions but I didn't figure out how the answers solve my problem:
Write a Maximum Monoid using Maybe in Haskell
Haskell Pattern Matching on the Empty Set

How would I rewrite the maximum' function to get it to work ?

解决方案

As C. A. McCann points out in his comment, you can't pattern match on values, only patterns.

The equation maximum' mempty = Nothing is actually equivalent to the equation maximum' x = Nothing. The argument gets bound to a name and Nothing is returned.

Here's a way to make your code work:

maximum' :: (F.Foldable a, Ord b, Eq (a b), Monoid (a b)) => a b -> Maybe b
maximum' xs
  | xs == mempty = Nothing
  | otherwise    = Just $ F.foldl1 max xs

I.e. you can compare the value xs against mempty. Note that we need a Monoid constraint to be able to get at the value mempty :: a b and an Eq constraint to be able to compare as well.

An other, more elegant, solution would be to use a fold to differentiate between the empty and non-empty cases:

maximum'' :: (F.Foldable a, Ord b) => a b -> Maybe b
maximum'' xs = F.foldl max' Nothing xs
  where max' Nothing x = Just x
        max' (Just y) x = Just $ max x y

这篇关于模式匹配中的Monoid mempty的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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