身份 Monad
這是在 JavaScript 中實現身份 monad 的示例,可以作為建立其他 monad 的起點。
基於 Douglas Crockford 關於 monad 和性腺的會議
使用這種方法重用你的函式會更容易,因為這個 monad 提供的靈活性和構圖噩夢:
f(g(h(i(j(k(value), j1), i2), h1, h2), g1, g2), f1, f2)
可讀,漂亮和乾淨:
identityMonad(value)
    .bind(k)
    .bind(j, j1, j2)
    .bind(i, i2)
    .bind(h, h1, h2)
    .bind(g, g1, g2)
    .bind(f, f1, f2);
function identityMonad(value) {
    var monad = Object.create(null);
    
    // func should return a monad
    monad.bind = function (func, ...args) {
        return func(value, ...args);
    };
    // whatever func does, we get our monad back
    monad.call = function (func, ...args) {
        func(value, ...args);
        return identityMonad(value);
    };
    
    // func doesn't have to know anything about monads
    monad.apply = function (func, ...args) {
        return identityMonad(func(value, ...args));
    };
    // Get the value wrapped in this monad
    monad.value = function () {
        return value;
    };
    
    return monad;
};
它適用於原始值
var value = 'foo',
    f = x => x + ' changed',
    g = x => x + ' again';
identityMonad(value)
    .apply(f)
    .apply(g)
    .bind(alert); // Alerts 'foo changed again'
還有物件
var value = { foo: 'foo' },
    f = x => identityMonad(Object.assign(x, { foo: 'bar' })),
    g = x => Object.assign(x, { bar: 'foo' }),
    h = x => console.log('foo: ' + x.foo + ', bar: ' + x.bar);
identityMonad(value)
    .bind(f)
    .apply(g)
    .bind(h); // Logs 'foo: bar, bar: foo'
讓我們嘗試一切:
var add = (x, ...args) => x + args.reduce((r, n) => r + n, 0),
    multiply = (x, ...args) => x * args.reduce((r, n) => r * n, 1),
    divideMonad = (x, ...args) => identityMonad(x / multiply(...args)),
    log = x => console.log(x),
    substract = (x, ...args) => x - add(...args);
identityMonad(100)
    .apply(add, 10, 29, 13)
    .apply(multiply, 2)
    .bind(divideMonad, 2)
    .apply(substract, 67, 34)
    .apply(multiply, 1239)
    .bind(divideMonad, 20, 54, 2)
    .apply(Math.round)
    .call(log); // Logs 29