谈谈我对Monad的理解

一、迷失于Monad的汪洋大海

第一次看见这个概念是两年前,这个词有着非常不通俗的翻译:“单子”。那时候受王垠影响在看Scheme和Haskell,对于Scheme的continuation和Haskell的Monad百思不得其解。直觉告诉我,这俩货之间有着千丝万缕的联系。当时对于类型可计算的概念也是毫无概念,作为刚从Java Web转到程序语言研究的我真是菜的不行,如饥似渴的在网上找资料各种读,越读越迷惑,后来不得不放下。

二、和Monad的几个照面

而后自己写了几个很菜的编译器,和性能啊新特性啊什么的毫不沾边。

看别人博客的文章照猫画虎也写过Monadic的语法分析器,也用过C#大法的Linq,然而并没有使我明白Monad是个啥。

Linq中的

from a in A
from b in B
from c in C
select f(a,b,c)

其实可以转化为这种结构:

A.SelectMany(a=>
    B.SelectMany(b=>
        C.Select(c=> f(a,b,c)
        )
    )
);

再后来在深入浅出node.js里见识了js的嵌套callback,因此看到了promise。
嵌套callback的代码:

A.fuck1(function(a){
    B.fuck2(function(b){
        C.fuck3(function(c){
            f(a,b,c);
        }
    }
});

promise把嵌套callback改写成这种风格(大概,伪代码):

Promise.then(A.fuck1)
       .then(B.fuck2)
       .then(C.fuck3)
       .then(function(a,b,c){
             f(a,b,c);
       })
       .done();

当时读来毫无感觉,现在细想毛骨悚然。

熟悉Scheme的孩子应该一眼就能发现这里面有CPS变换。

所谓CPS变换就是把所有g(f(x))都给改写成f(x, r=>g(r))的过程。然而这有和Monad有什么关系?Monad到底是个啥?

CPS变换和Monad是一家亲。CPS变换是说变换过程,而Monad是具备某种能力的“对象”。所谓具备某种能力其实就是Monad具备这种把嵌套式的金字塔结构打平成链式结构的能力。Promise差不多算是和Linq有异曲同工之妙。两者都是Monad的应用。Monad的定义涉及了一些类型计算,其实是很简单的东西,只是写成学术符号立刻让人看不懂了。

最近读了一篇文章联想起之前的Linq和promise,仿佛是有点恍然大悟的感觉。

在Swift里,“一个实现了 flatMap方法的类型其实就是 monad”。

public func flatMap(f: (Wrapped) -> U?) -> U? { 
    switch self { 
        case .Some(let y): return try f(y) 
        case .None: return .None 
    }
}

flatMap接受一个函数f做参数,返回一个Optinal U类型。f接受Optional类型包裹的类型,返回Optinal U类型。
下面是Optional的定义:

enum Optional { 
    case None 
    case Some(T)
}

这只是一个很小的关于Optianal的简单例子,其实实现了flatMap的类都可以称作Monad。

当然Monad可不仅仅是这样,当年在Haskell里面反正是看的云里雾里。熟悉类型推导的孩子可以推导一下类型,看看为毛promise可以写成那样。哦,我忘了,js是弱类型的!

其实这篇文章我倒没打算把Monad讲明白,因为毕竟我是跌跌撞撞走过了很多弯路才明白了类型计算,continuation才最终走到了Monad面前,不敢说自己有什么理解,只是通俗的明白了这货原来真的有用,而且用的还不少,只是学术性太强导致曾经看过的资料总有些说不清道不明,感觉有道鸿沟横在眼前。

之所以写这篇是因为我知道这个概念太久,如鲠在喉。

贴上两篇有启发的文章:

http://www.infoq.com/cn/articles/swift-brain-gym-monad?utm_campaign=rightbar_v2&utm_source=infoq&utm_medium=articles_link&utm_content=link_text

http://www.cppblog.com/vczh/archive/2013/07/27/202154.html

最后感慨一下,vczh大神的高度果然不是我这等渣渣可以企及的。当年太菜没看懂几篇vczh的博客,泪流满面。

你可能感兴趣的:(谈谈我对Monad的理解)