我试图写一个类似于maximum
的通用Prelude
函数。我的第一个朴素方法看起来像这样:maximum' :: (F.Foldable a, Ord b) => a b -> Maybe b
maximum' mempty = Nothing
maximum' xs = Just $ F.foldl1 max xs
但是,当我对其进行测试时,无论输入如何,它总是返回Nothing
:> maximum' [1,2,3]
> Nothing
现在,我想知道是否有可能获得Monoid类型实例的空值。我编写的测试功能可以正常工作:getMempty :: (Monoid a) => a -> a
getMempty _ = mempty
> getMempty [1,2,3]
> []
我已经看过这两个问题,但是我没有弄清楚答案如何解决我的问题:
Write a Maximum Monoid using Maybe in Haskell
Haskell Pattern Matching on the Empty Set
我将如何重写maximum'
函数以使其正常工作?
最佳答案
正如 C. A. McCann 在他的评论中指出的那样,您不能对值进行模式匹配,只能对模式进行匹配。
等式 maximum' mempty = Nothing
实际上等价于等式 maximum' x = Nothing
。参数绑定(bind)到一个名称并返回 Nothing
。
这是使您的代码工作的一种方法:
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
IE。您可以将值
xs
与 mempty
进行比较。请注意,我们需要一个 Monoid
约束才能获得值 mempty :: a b
和一个 Eq
约束才能进行比较。另一个更优雅的解决方案是使用折叠来区分空和非空情况:
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
关于haskell - 模式匹配中的Monoid mempty,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12216886/