我目前正在阅读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。:我不知道什么是更好的方式来描述"取消前期计算"除了"短路"?
之外的行为答案 0 :(得分:0)
guard
有Applicative
约束,因为您不需要对其执行monadic操作来定义函数。
它的定义是(从Hackage source复制):
guard :: (Alternative f) => Bool -> f ()
guard True = pure ()
guard False = empty
如果指定MonadPlus
而不是Alternative
,则不会获得任何收益。 MonadPlus
是Alternative
的子类,因此所有MonadPlus
个实例都可以使用guard
,但并非所有Alternatives
都可以使用它。
(虽然 很少有被排除Alternatives
的案例 - 但提到here的案例都有MonadPlus
的实例,即使他们没有满足左分配规则。)
一般来说,最好坚持编写函数所需的最低限度,即使预期用途更具体。通过这种方式,没有任何事情可以排除,并且不会有类型可以为其工作但不是单子的人的投诉。
巧合的是,Hoogle search results错误地显示了MonadPlus
限制,但如果您点击该链接是正确的。