jbe*_*man 5 monads haskell applicative
ap没有文档说明的规范,请阅读并指出可能是的注释<*>,但这并不是出于实际原因:
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 = (<*>)
Run Code Online (Sandbox Code Playgroud)
所以我承担ap的(<*>) = ap法律是简写“AP的右手边”,实际上法律表达之间的关系>>=,return以及<*>对不对?否则,法律将毫无意义。
我正在考虑上下文Validation,并且似乎没有合法的Monad实例是多么令人不满意。我也在考虑ApplicativeDo,以及这种转换如何使我们从Monad实例的实际效果中恢复Validation;我最常想做的是尽可能地累积错误,但在必要时仍然能够使用bind。实际上bindV,我们导出了几乎在所有地方都需要使用的功能,这很荒谬。我能想到的唯一的实际后果是,我们会根据所使用的合成类型(或程序在理论上如何通过重写规则来转换)来累积不同或更少的错误,尽管我不确定为什么应用合成会转换为单子)。
编辑:在相同法律的文档Monad是更广泛:
此外,Monad操作和应用操作应与以下内容相关:
Run Code Online (Sandbox Code Playgroud)pure = return (<*>) = ap上述法律暗示:
Run Code Online (Sandbox Code Playgroud)fmap f xs = xs >>= return . f (>>) = (*>)
“上述法律意味着”……那么这里是否是我们真正关心的真正法律的想法?
但是现在我离开试图在的上下文中了解这些Validation。第一条定律将成立。如果我们仅定义,第二个显然可以成立(>>) = (*>)。
但是Monad令人惊讶的是,该文档并未说明>>应如何关联(除非我只是想念它)。大概我们想要那个
a >> b = a >>= \_ -> b
Run Code Online (Sandbox Code Playgroud)
...并且(>>)包含在类中,以便可以提高效率,而这从来没有完全纳入文档中。
所以,如果这是的话,那么我想办法Monad和Applicative相关居然是这样的:
return = pure
xs >>= return . f = fmap f xs
a >>= \_ -> b = fmap (const id) a <*> b
Run Code Online (Sandbox Code Playgroud)
每个Monad都会产生一个Applicative,并且对于该诱导的Applicative,<*> = ap将定义地成立。但是给定两个结构 -Monad m和- 如果没有两个定律和 ,Applicative m则不能保证这些结构一致。例如,采用列表的“常规”实例和 zip-list实例。虽然与实例不一致从根本上来说并没有什么“错误” ,但它可能会让大多数用户感到困惑,因此法律禁止这样做。<*> = appure = returnMonadApplicativeMonadApplicativeMonad
tl;dr 所讨论的法律旨在确保这一点,Monad并Applicative以直观明显的方式达成一致。