我试图写一个类似于maximum的通用Prelude函数。我的第一个朴素方法看起来像这样:maximum' :: (F.Foldable a, Ord b) => a b -> Maybe bmaximum' mempty = Nothingmaximum' xs = Just $ F.foldl1 max xs
但是,当我对其进行测试时,无论输入如何,它总是返回Nothing:> maximum' [1,2,3]> Nothing
现在,我想知道是否有可能获得Monoid类型实例的空值。我编写的测试功能可以正常工作:getMempty :: (Monoid a) => a -> agetMempty _ = 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。您可以将值 xsmempty 进行比较。请注意,我们需要一个 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/

10-10 22:58