为什么`guard`没有用MonadPlus约束定义?

时间:2017-02-04 05:59:28

标签: haskell monads

我目前正在阅读wikibooks中的Alternative / MonadPlus类型类。它很好地描述了这种差异。然而,一个令人费解的部分是guard函数,我假设它用于"短路"计算。 (我是对的吗?)

虽然guard中定义的Control.Monad函数有一个Alternative约束,但如下所示(link)。

guard           :: (Alternative f) => Bool -> f ()
guard True      =  pure ()
guard False     =  empty

但上述文章提到,只有MonadPlus才能强制执行左零和右零定律(因此声称更强)。

mzero >>= f  =  mzero -- left zero
m >> mzero   =  mzero -- right zero

鉴于guard函数的用途,不应该用MonadPlus约束来定义它?如果guard应该{&1 34}短路,那么我们不需要更强大的法律。计算?我很好奇特定设计选择背后的原因。

p.s。:我不知道什么是更好的方式来描述"取消前期计算"除了"短路"?

之外的行为

1 个答案:

答案 0 :(得分:0)

guardApplicative约束,因为您不需要对其执行monadic操作来定义函数。

它的定义是(从Hackage source复制):

guard           :: (Alternative f) => Bool -> f ()
guard True      =  pure ()
guard False     =  empty

如果指定MonadPlus而不是Alternative,则不会获得任何收益。 MonadPlusAlternative的子类,因此所有MonadPlus个实例都可以使用guard,但并非所有Alternatives都可以使用它。

(虽然 很少有被排除Alternatives的案例 - 但提到here的案例都有MonadPlus的实例,即使他们没有满足左分配规则。)

一般来说,最好坚持编写函数所需的最低限度,即使预期用途更具体。通过这种方式,没有任何事情可以排除,并且不会有类型可以为其工作但不是单子的人的投诉。

巧合的是,Hoogle search results错误地显示了MonadPlus限制,但如果您点击该链接是正确的。