monad ,chain, monoid,applicative 介绍

196 阅读2分钟
  • monad 相当于是一个基于值形成的新的数据结构, 这个数据结构里有 map 的方法函数。
function Just(val) {
    return { map };

    function map(fn) { return Just( fn( val ) ); }

}

返回的 B 依然是个 带有 map 方法的数据结构

var A = Just( 10 );
var B = A.map( v => v * 2 ); // 20
  • chain 作为 bind、flatMap, 它的作用是 flatten 或 unwrap,也就是说它可以展开被 Just 封装的值 val。你可以使用 chain 将一个函数作用到一个包装的值上,返回一个结果值
function Just(val) {
    return { map, chain };
    
    function map(fn) { return Just( fn( val ) ); }
   
     // aka: bind, flatMap
    function chain(fn) { return fn( val ); }
}

通过 chain flat 后 此时的 B 是数据类型 20

var A = Just( 10 );
var B = A.chain( v => v * 2 ); // 20
  • monoid: compose 函数接收的函数都要符合一致性的 fn :: v -> v 函数签名,也就是说函数接收的参数和返回的值类型要一样。那么,满足这些类型签名的函数就组成了 monoid 下面 identity 函数即为 monoid
function identity<T>(arg: T): T {
    return arg;
}

identity 在 monad 中有一个用处,就是如果把 identity 作为一个参数,可以起到观察 inspect 的作用。比如,我们先用 Just 来封装 15 这个值,然后调用 chain 的方法时,把 identity 作为参数,返回的就是一个 flatten 或 unwrap 展开的 15。所以我们可以看出,它也起到了一个 log 的作用。

var A = Just( 15 );
A.chain (identity) // 返回 15
  • applicative 应用函子(applicative),简称 ap, ap 的作用其实也很简单。应用函子,它的作用是可以把一个封装过的函数应用到一个包装过的值上。
function Just(val) {
    return { map, ap };

    function map(fn) { return Just( fn( val ) ); }

    function ap(anotherMonad) { return anotherMonad.map( val ); }

}
var A = Just( 6 );
var B = Just( 10 );

function add(x,y) { return x + y; }

var C = A.map( curry( add ) ).ap( B );

C.chain(identity); // 返回 16
function Just(val) {
    return { map, chain, ap, log };

    // *********************

    function map(fn) { return Just( fn( val ) ); }

    // aka: bind, flatMap
    function chain(fn) { return fn( val ); }

    function ap(anotherMonad) { return anotherMonad.map( val ); }

    function log() {
        return `simpleMonad(${ val })`;
    }
}

函子和应用函子,我们也可以看一下,在数组中,有一个 array.of 的工厂方法,它的作用是接收一组参数,形成一个新数组

var arr = Array.of(1,2,3,4,5); // 返回:[1,2,3,4,5]

在函数式编程中,我们称实现了 of 工厂方法的函子是 pointed 函子。通过 pointed 函子,我们可以把一组值放到了一个数组的容器中,之后还可以通过映射函子对每个值做映射。而应用函子,(applicative functor)就是实现了应用方法的 pointed 函子。

具体含义可参考, blog.oyanglul.us/grokking-mo…