“(< *>)= ap"适用/单子法则与这两个类别之间的关系到底如何? [英] How exactly does the `(<*>) = ap` Applicative/Monad law relate the two classes?
问题描述
ap
没有文档说明,并且带注释的说明可能是<*>
,但并非出于实际原因:
ap
doesn't have a documented spec, and reads with a comment pointing out it could be <*>
, but isn't for practical reasons:
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }
-- Since many Applicative instances define (<*>) = ap, we
-- cannot define ap = (<*>)
所以我假设(<*>) = ap
法则中的ap
是"ap右侧"的简写,而该法则实际上表示了>>=
,return
和<*>
之间的关系?否则法律就没有意义.
So I assume the ap
in the (<*>) = ap
law is shorthand for "right-hand side of ap" and the law actually expresses a relationship between >>=
, return
and <*>
right? Otherwise the law is meaningless.
上下文是我在考虑Validation
的原因,它似乎似乎没有合法的Monad
实例,这是多么令人不满意.我也在考虑ApplicativeDo
以及这种转换方式如何使我们从Validation
实例的Monad
实例的实际效果中恢复过来;我最想做的是尽可能地累积错误,但是在必要时仍然可以使用bind.实际上,我们导出了一个bindV
函数,几乎在所有地方都需要使用它,这很荒谬.我能想到的唯一的实际后果是,我们会根据使用的合成类型(或程序在理论上如何通过重写规则进行转换)来累积不同或更少的错误,尽管我不确定为什么应用合成会转换为单子).
The context is me thinking about Validation
and how unsatisfying it is that it can't seem to have a lawful Monad
instance. I'm also thinking about ApplicativeDo
and how that transformation sort of lets us recover from the practical effects of a Monad
instance for Validation
; what I most often want to do is accumulate errors as far as possible, but still be able to use bind when necessary. We actually export a bindV
function which we need to use just about everywhere, it's all kind of absurd. The only practical consequence I can think of the lawlessness is that we accumulate different or fewer errors depending on what sort of composition we use (or how our program might theoretically be transformed by rewrite rules, though I'm not sure why applicative composition would ever get converted to monadic).
编辑:Monad
中有关相同法律的文档更加详尽:
EDIT: The documentation for the same laws in Monad
is more extensive:
此外,Monad和Applicative运算应关联如下:
Furthermore, the Monad and Applicative operations should relate as follows:
pure = return
(<*>) = ap
以上法律暗示:
fmap f xs = xs >>= return . f
(>>) = (*>)
上述法律意味着"……那么,这里是否有这些是我们真正关心的真正法律呢?
"The above laws imply"... so is the idea here that these are the real laws we care about?
但是现在我离开尝试在Validation
的上下文中理解这些内容.第一条定律将成立.如果仅定义(>>) = (*>)
,显然可以保留第二个.
But now I'm left trying to understand these in the context of Validation
. The first law would hold. The second could obviously be made to hold if we just define (>>) = (*>)
.
但是Monad
的文档出乎意料的是,对于>>
应该如何关联,根本没有任何内容(除非我只是想念它).大概是我们想要的
But the documentation for Monad
surprisingly says nothing at all (unless I'm just missing it) about how >>
should relate. Presumably we want that
a >> b = a >>= \_ -> b
...和(>>)
包含在类中,以便可以提高效率,而这从来没有完全纳入文档中.
...and (>>)
is included in the class so that it can be overridden for efficiency, and this just never quite made it into the docs.
因此,如果是情况,那么我想Monad
和Applicative
的联系方式实际上是这样的:
So if that's the case, then I guess the way Monad
and Applicative
relate is actually something like:
return = pure
xs >>= return . f = fmap f xs
a >>= \_ -> b = fmap (const id) a <*> b
推荐答案
每个Monad
都会产生一个Applicative
,并且对于引起的Applicative
,<*> = ap
将在定义上成立.但是给定两个结构-Monad m
和Applicative m
-如果没有两个法律<*> = ap
和pure = return
,则不能保证这些结构一致.例如,以'regular'Monad
实例为列表,并以zip-list Applicative
实例为例.对于Monad
和Applicative
实例,从根本上没有什么错",但它可能会使大多数用户感到困惑,因此,Monad
法规禁止这样做.
Every Monad
gives rise to an Applicative
, and for that induced Applicative
, <*> = ap
will hold definitionally. But given two structures - Monad m
and Applicative m
- there is no guarantee that these structures agree without the two laws <*> = ap
and pure = return
. For example, take the 'regular' Monad
instance for lists, and the zip-list Applicative
instance. While there is nothing fundamentally 'wrong' about a Monad
and Applicative
instance disagreeing, it would probably be confusing to most users, and so it's prohibited by the Monad
laws.
tl; dr相关法律旨在确保Monad
和Applicative
以直观的明显方式达成共识.
tl;dr The laws in question serve to ensure that Monad
and Applicative
agree in an intuitively obvious way.
这篇关于“(< *>)= ap"适用/单子法则与这两个类别之间的关系到底如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!