Created
July 31, 2013 12:59
-
-
Save nakamura-to/6121758 to your computer and use it in GitHub Desktop.
JavaScriptでMaybeモナド - Douglas Crockfordの実装とECMA Script 6のgeneratorを使った実装の比較
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Douglas CrockfordのMaybeモナド | |
// | |
// http://www.youtube.com/watch?v=b0EF0VTs9Dc | |
// 上記のyoutubeより(時間にして21:50, 26:50, 27:15のコード) | |
function MONAD(modifier) { | |
var prototype = Object.create(null); | |
return function unit(value) { | |
var monad = Object.create(prototype); | |
monad.bind = function (func, args) { | |
return func.apply(undefined, [value].concat(Array.prototype.slice.apply(args || []))); | |
}; | |
if (typeof modifier === 'function') { | |
modifier(monad, value); | |
} | |
return monad; | |
}; | |
} | |
var maybe = MONAD(function (monad, value) { | |
if (value === null || value === undefined) { | |
monad.is_null = true; | |
monad.bind = function () { | |
return monad; | |
}; | |
} | |
}); | |
// example 1 | |
var monad = maybe(1); | |
monad.bind(function (value) { | |
monad = maybe(value + 2); | |
monad.bind(function (value) { | |
console.log(value); // 3 | |
}); | |
}); | |
// example 2 | |
monad = maybe(null); | |
monad.bind(function (value) { | |
monad = maybe(value + 2); | |
monad.bind(function (value) { | |
console.log(value); // unreachable | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ECMA Script 6 のgeneratorを使ったMaybeモナド | |
// | |
// 実装は https://github.com/nakamura-to/mflow より | |
// node v0.11.4で --harmony-generators オプションをつけて稼動確認 | |
function maybe(fn) { | |
var gen = fn(); | |
var ret = gen.next(); | |
while (!ret.done) { | |
if (ret.value == null) return null; | |
ret = gen.next(ret.value); | |
} | |
return ret.value; | |
} | |
// example 1 | |
maybe(function * () { | |
var value = yield 1; | |
value = yield value + 2; | |
console.log(value); // 3 | |
}); | |
// example 2 | |
maybe(function * () { | |
var value = yield null; | |
value = yield value + 2; | |
console.log(value); // unreachable | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment