美文网首页
谈谈我对Monad的理解

谈谈我对Monad的理解

作者: 三生石上绛珠草 | 来源:发表于2016-05-25 00:10 被阅读2231次

    一、迷失于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<U>(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<T> { 
        case None 
        case Some(T)
    }
    

    这只是一个很小的关于Optianal<T>的简单例子,其实实现了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的理解

          本文链接:https://www.haomeiwen.com/subject/axozrttx.html