申请人撰写,monads不 [英] Applicatives compose, monads don't

查看:78
本文介绍了申请人撰写,monads不的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


申请人撰写,monads不需要。

以上陈述意味着什么?如果我们比较类型

 (*):: Applicative a =>> a(s  - > t) - >一个s  - > a t 
(>> =):: Monad m => m s - > (s - > m t) - > m t

我们知道分离这两个概念的线索。 (>> =)类型中的(s - > mt) s 可以确定 mt 中的计算行为。 Monads允许值和计算层之间的干扰。 (<*>)运算符不允许这样的干扰:函数和参数计算不依赖于值。这真的很有趣。比较

  miffy :: Monad m => m Bool  - > m x  - > m x  - > mx 
miffy mb mt mf = do
b < - mb
if b then mt else mf

,它使用某种效果的结果来决定两次计算(例如发射导弹和签署停战协议),而

  iffy :: Applicative a =>一个Bool  - > a x  - > a x  - >在af =纯粹的情况下,x 
iffy ab * ab *在< *> af其中
cond btf = if b then t else f

它使用 ab 在和 af之间选择两个计算的值

>> =)从一个值中选择一个计算,这可能很重要。但是,支持这种力量使得monad很难组成。如果我们尝试构建双重绑定,则可以使用b-b Monad m,Monad n)=> m(n s) - > (s→m(n t))→> m(n t)
mns>>>>> == f = mns>> - { - m-} \ ns - >让nmnt = ns>> =(return .f)in ???

我们得到了这个结果,但现在我们的图层都混乱了。我们有一个 n(m(n t)),所以我们需要去掉外部的 n 。正如Alexandre C所说,如果我们有一个合适的

  swap :: n(m t) - > m(nt)

来置换 n 向内和加入到另一个 n



较弱的<双重应用>定义b
$ b

 (<< ** >>)::(本申请a,申请人b) => a(b(s→t))→> a(b s) - > a(b t)
abf< **>> abs =纯(*)* * abf * abs

因为层之间没有干扰。

相应地,当你确实需要 Monad s的额外功能时很好地认识到,当你可以避开刚性计算结构 Applicative 支持。



请注意,顺便提一下,虽然组成monad很困难,但可能比您需要的多。类型 m(nv)表示使用 m --effects进行计算,然后使用 n - 对 v -value的影响,其中 m - 影响在 n -effects start(因此需要 swap )。如果你只是想将 m - 影响与 n - 效果相交错,那么构图可能太多了! / p>

Applicatives compose, monads don't.

What does the above statement mean? And when is one preferable to other?

解决方案

If we compare the types

(<*>) :: Applicative a => a (s -> t) -> a s -> a t
(>>=) :: Monad m =>       m s -> (s -> m t) -> m t

we get a clue to what separates the two concepts. That (s -> m t) in the type of (>>=) shows that a value in s can determine the behaviour of a computation in m t. Monads allow interference between the value and computation layers. The (<*>) operator allows no such interference: the function and argument computations don't depend on values. This really bites. Compare

miffy :: Monad m => m Bool -> m x -> m x -> m x
miffy mb mt mf = do
  b <- mb
  if b then mt else mf

which uses the result of some effect to decide between two computations (e.g. launching missiles and signing an armistice), whereas

iffy :: Applicative a => a Bool -> a x -> a x -> a x
iffy ab at af = pure cond <*> ab <*> at <*> af where
  cond b t f = if b then t else f

which uses the value of ab to choose between the values of two computations at and af, having carried out both, perhaps to tragic effect.

The monadic version relies essentially on the extra power of (>>=) to choose a computation from a value, and that can be important. However, supporting that power makes monads hard to compose. If we try to build ‘double-bind’

(>>>>==) :: (Monad m, Monad n) => m (n s) -> (s -> m (n t)) -> m (n t)
mns >>>>== f = mns >>-{-m-} \ ns -> let nmnt = ns >>= (return . f) in ???

we get this far, but now our layers are all jumbled up. We have an n (m (n t)), so we need to get rid of the outer n. As Alexandre C says, we can do that if we have a suitable

swap :: n (m t) -> m (n t)

to permute the n inwards and join it to the other n.

The weaker ‘double-apply’ is much easier to define

(<<**>>) :: (Applicative a, Applicative b) => a (b (s -> t)) -> a (b s) -> a (b t)
abf <<**>> abs = pure (<*>) <*> abf <*> abs

because there is no interference between the layers.

Correspondingly, it's good to recognize when you really need the extra power of Monads, and when you can get away with the rigid computation structure that Applicative supports.

Note, by the way, that although composing monads is difficult, it might be more than you need. The type m (n v) indicates computing with m-effects, then computing with n-effects to a v-value, where the m-effects finish before the n-effects start (hence the need for swap). If you just want to interleave m-effects with n-effects, then composition is perhaps too much to ask!

这篇关于申请人撰写,monads不的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆