我目前正在阅读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被认为是“短路”计算,我们不需要更强大的定律吗?我很好奇具体设计选择背后的原因。
附言:除了“短路”这个词之外,我不知道还有什么更好的方式来描述“取消前期计算”的行为?
发布于 2017-04-18 07:57:15
guard有一个Applicative约束,因为您不需要在它上执行一元操作来定义函数。
它的定义是(从Hackage source复制):
guard :: (Alternative f) => Bool -> f ()
guard True = pure ()
guard False = empty如果它指定的是MonadPlus而不是Alternative,那么它不会得到任何东西。MonadPlus是Alternative的子类,因此所有MonadPlus实例都可以使用guard,但并非所有Alternatives都可以使用它。
(尽管排除Alternatives的情况很少--前面提到的两种情况here都有一个MonadPlus实例,尽管它们不满足左分布规则。)
一般而言,最好坚持编写函数所需的最低限度的限制,即使目标用途更加具体。这样,就没有什么不应该被排除的东西了,也没有来自那些可以为它工作但不是monads的人的抱怨。
巧合的是,Hoogle search results错误地显示了MonadPlus限制,但如果您单击该链接,它是正确的。
https://stackoverflow.com/questions/42037064
复制相似问题