- 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…