为什么monad类型类中存在fail方法?

时间:2015-05-30 11:46:30

标签: haskell pattern-matching monads do-notation

所以我有这行代码:

[Nothing] >>= \(Just x) -> [x]

当然会给出异常,因为该模式与Nothing不匹配。

另一方面,此代码给出了不同的结果,[]:

do
  Just x <- [Nothing]
  return x

在我看来,它们应该产生相同的结果,因为do-blocks应该被用于使用(&gt;&gt; =)并返回。但实际情况并非如此,使得注释成为一种特征,而不是语法糖。

我知道monad类型类中存在失败,我知道在do-block中模式匹配失败时会调用它,但我不能理解为什么它是一个想要的行为应该不同于使用正常的monad操作。

所以我的问题是 - 为什么要存在失败方法?

1 个答案:

答案 0 :(得分:1)

代码如

\(Just x) -> ...

表示功能。只有一种方法可以使用这样的值:将它应用于某个参数。当所述参数与模式不匹配(例如Nothing)时,应用程序是不可能的,并且唯一的通用选项是引发运行时错误/异常。

相反,当在do - 块中时,我们有一个类型类:monad。从理论上讲,这类课程可以扩展到为这种情况提供行为。实际上,Haskell的设计者决定为这种情况添加fail方法。

选择是好还是坏都可能引起争议。只是为了呈现另一个设计选项,Monad类可以设计为没有fail,而像

这样的块
do ... 
   Just x <- ...
   ...

可能被禁止,或者需要Monad的特殊MonadFail子类。错误输出也是一种选择,但我们喜欢写例如。

catMaybes xs = do Just x <- xs
                  return x
-- or
catMaybes xs = [ x | Just x <- xs ]

从列表中删除Nothing