我目前正在读关于另类/ MonadPlus类型类维基教科书.它很好地描述了这种差异.然而,一个令人费解的部分是guard我假设的函数用于"短路"计算.(我对吗?)
guard虽然定义的函数Control.Monad有一个Alternative约束,如下(链接).
guard :: (Alternative f) => Bool -> f ()
guard True = pure ()
guard False = empty
Run Code Online (Sandbox Code Playgroud)
但是上面的文章提到只MonadPlus需要强制执行左零和零零定律(因此更强的主张).
mzero >>= f = mzero -- left zero
m >> mzero = mzero -- right zero
Run Code Online (Sandbox Code Playgroud)
鉴于guard函数的目的,不应该用MonadPlus约束来定义它吗?如果guard应该"短路"计算,我们不需要更强的定律吗?我很好奇特定设计选择背后的原因.
ps:我不知道什么是比"短路"这个词更好的描述"取消前期计算"行为的方法?
guard有一个Applicative约束,因为您不需要对其执行一元操作来定义函数。
它的定义是(从Hackage 源复制):
guard :: (Alternative f) => Bool -> f ()
guard True = pure ()
guard False = empty
Run Code Online (Sandbox Code Playgroud)
如果它指定MonadPlus而不是Alternative,它就不会获得任何东西。 MonadPlus是 的子类Alternative,因此所有MonadPlus实例都可以使用guard,但并非所有实例都Alternatives可以使用它。
(尽管排除的情况很少——这里Alternatives提到的两种情况都有一个实例,即使它们不满足左分配规则。)MonadPlus
一般来说,最好坚持编写函数所需的最低限制,即使预期用途更具体。这样,就不会出现任何不应该被排除的情况,也不会出现那些类型可以适用但不是 monad 的人的抱怨。
巧合的是,Hoogle 搜索结果错误地显示了MonadPlus限制,但如果您单击该链接,它是正确的。
| 归档时间: |
|
| 查看次数: |
311 次 |
| 最近记录: |