YAME — Yet Another Monad Explaination

Monad有什么难的?自函子范畴上的一个幺半群而已。

理论上的Monad按照定义理解就可以了,而实际应用中Monad在我看来是一个带context的值(这个context可以存在,或尚未存在)。return函数返回一个无论context都包含有它的参数的Monad,(>>=)函数把一个函数apply到Monad内部的确切的值上,当内部还不存在确切值时,计算被暂停,等待一个确切值的出现。(有点类似currying/Cont/State的概念)或者可能不存在值,此时计算被取消了。

1.列表Monad

这个Monad的context尚未存在,在给定了一个下标context之后,能够获得一个确切的值。return函数返回一个只含一个元素的列表,使得这个monad的值被确定了(任何合法的context都会返回确定的值)。(>>=)把一个函数map进列表,但是这时monad的值由于缺乏context还无法确定,所以函数会在取得了确定的context之后起效(这是从lazy evaluation的角度上看;如果从strict evaluation上来说,因为无法确定以后哪个可能的值会被访问,所以必须把所有可能的值都用函数运算一遍)。如果把一个函数(>>=)进空列表,因为不存在值,所以计算被取消了。

2. Maybe Monad

这个Monad是一个有着两种context(Just或Nothing)的值。return返回一个只包含了给定的值的monad(Just x)。如果context是Just,那么(>>=)把函数map到Monad内部的值上。如果context是Nothing,那么根本就没有头发值,因此计算被取消。

3. Either Monad

这个Monad带着一个比Maybe信息更丰富的context(Left)。取值为Left [some info]或者Right [some value]。基本上和Maybe相同。

4. IO Monad

这个Monad的context尚未存在,在给定了某一个时刻的一个外部世界context后,能够获得一个确切的值。return返回一个无论外部世界的context如何都包含了给定参数的monad。(>>=)试图把一个函数apply到这个Monad内部的值上,但是由于缺少Context,值还处于量子态,所以函数等待到确定的值出现后再起效。

5. 函数Monad(a.k.a reader Monad)

这个Monad的context尚未存在,在给定了一个参数context后,能够获得一个确切的值。return返回一个无论参数context是什么都返回给定值的monad。f >>= g在g获得一个context前无法给f一个确切的参数,所以必须等g获得context后再和context一起feed f。为什么那么诡异,而不是像functor那样只是函数复合?因为类型系统呀。

instance Monad ((->) r) where
    (>>=) :: ((->) r a) -> (a -> ((->) r a)) -> ((->) r a)
    h >>= f = \w -> f (h w) w

6. State Monad

这个Monad的context尚未存在,在给定了一个state context后,能够获得一个确切的值。return理所当然返回一个无论state context如何都能返回一个固定值得monad。f >>= s试图把一个f函数map到s里面的值上,但是只能等state context出现塌缩为一个确切值后才能进行。由于f必须返回一个新的state(换言之,返回另一个运算),而且是在冬堡坍缩前返回,坍缩后,f应该返回一个(Value, State)。至于为什么是用原始运算的值作为f的参数产生新State然后用上一次运算的状态runState,没办法,这是Monad Laws决定的。(话说State这个名字有点误导,让人以为里面包含了一个State,实际上应该叫Transition)

所以其实如果GHC能够通过runState作出正确的推导,state monad的(>>=)可以定义为这样(不要搞混State和S!State指transition, S指literally state)

instance Monad (State s) where
    runState (state >>= f) s =
        let
            (midV, midS) = runState state s
            (newV, newS) = runState (f midV) midS
        in (newV, newS)

7. Cont Monad

这个Monad的context尚未存在,在给定了一个continuation context后,能够获得一个确切的值。别的基本和State Monad相同。这个Monad相当有意思,有时间专门写一篇笔记。

8. STM/ST Monad

这两个Monad存粹是为了用类型系统来限制用户的操作,没什么实际含义。