[关闭]
@MiloXia 2015-04-16T02:41:19.000000Z 字数 1810 阅读 2223

Monad

函数式编程


只是一种设计模式,是对计算的抽象,注意:计算;如同使用策略模式要抽出接口一样,monad也要定义return 和 bind。大家只是被他的功能及表现力吓到了,封装副作用,封装值,封装操作,封装并发,balabala。。。

用大神的话来说
不就是自函子范畴里的幺半群么
在我看来
它只是一个实现 F(F a) = F a 的(flatten)组合子而已
不要喷我...
还有 不要老想着定义一个单子出来,十有八九你已经在过度设计了


补充
解释一下大神的话,首先什么叫自函子?
用haskell来举例的话,Maybe a 是一个函子Functor,所有的(Maybe int, Maybe string, Maybe ...)就是Maybe的范畴,那么自函子怎么表达?
Maybe a map over Maybe a 之后还是落在Maybe a:
Just 9 >>= Just(* 10) = Just(90)
(注:我故意把\x -> return(x * 10) 写成结果 Just(* 10) 是有原因的)
看上面的栗子得出两个结论:
1. bind也就是 >>= 实现了 Maybe(Maybe a) = Maybe a
2. 所有的具体类型{Maybe(Maybe int) = Maybe int, Maybe(Maybe string) = Maybe string...}就是Maybe自函子范畴
接下来就简单了,幺半群什么鬼?就是monoid ,monoid的定义是:
mempty :: m
mappend :: m -> m -> m
用人话讲,就是一个原子(幺元)和一个二元操作,来看看monad的定义,return和bind
return 返回的是什么,就是一个mempty,list里面是[],int里面是1
bind干了什么?list的二元操作是++,int是+,那么单子的bind呢?
不也是个二元操作吗?
Just 9 >>= Just(* 10) = Just(90)
这个操作比较特殊,因为他是来做子函子范畴映射的,而不是1+1 = 2,或 “ab” ++ "c" = "abc"
明白了吗?Monad就是一个Monoid
不服?跑个分,啊不,验证一下
只要单子满足Monoid laws就行,满足吗? 满足
Monoid laws:mempty 相对于 mappend 必须要表现成 identity
Monoid laws:遵守结合律 (xmappendy)mappendz = xmappend(ymappendz)
再看单子律:
Monad laws:return 满足 Left identity 跟 right identity
Monad laws:用 >>= 把一串 monadic function 串在一起,他们的先后顺序不应该影响结果:
(m >>= f) >>= g 跟 m >>= (\x -> f x >>= g) 是相等的 也就是结合律
再回到代码:
Just 9 >>= Just(* 10) = Just(90)
把第二个参数换成函数:\x -> return (x*10) 这才是单子高明之处,它必须是一个接受普通参数,并返回monadic value的函数,这就造成了震惊世界的作用:抽象了计算
怎么就抽象了计算了呢?通过这种形式的抽象,很容易实现大神所说的CPS,不懂CPS? 没关系,
《Functional_Programming_in_Scala》一书第六章 Purely functional state就是将的CPS,状态传递模式,《趣学haskell》讲state时也讲了,只是人家没说 this is CPS!
《Functional_Programming_in_Scala》一书第十章提出单子,而且立马就用单子实现了state,你会发现很像CPS
Monad另一个高明的地方就是,F a的 a,a代表类型,函数也是有类型的,用F包一下函数,就可以不仅仅将副作用做流式变化那么简单了,而是可以实现函数的流式调用了,或者叫有序调用了,又或者叫传递调用。。。
依然是《Functional_Programming_in_Scala》一书第13章IO这个单子用scala写出来,你会发现,就如大神所说的,单子就是个分号和return
def run = { self.run; io.run }
而且作者也是从monoid推导到monad的
最碉堡的是scala的future也是单子,用单子封装并发
能做到这些,完全是因为单子抽象了,计算的模式,它让一切带有context(也就是范畴)的值以固定模式做计算,结果不会逃离原context;
说白了就是一个实现了 F(F a) = F a 的组合子而已

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注