-
-
Save scott-christopher/5069a91b924e7e182caa to your computer and use it in GitHub Desktop.
Fantasy-Land monads and ES6 generators
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
module.exports = (genFunc) => (...args) => { | |
const generator = genFunc(...args); | |
const cont = arg => { | |
const {done, value} = generator.next(arg); | |
return done ? value : value.chain(cont); | |
}; | |
return cont(); | |
} |
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
const | |
genDo = require('./gen-do'), | |
Option = require('fantasy-options'), | |
phonebook = { 'schristo': '+61491570156' }, | |
govDb = { '+61491570156': 'abc123' }, | |
taxDb = { 'abc123': 'def456' }, | |
lookup = (k, obj) => | |
(k in obj) ? Option.Some(obj[k]) : Option.None, | |
taxCodeLookup = genDo(function*(name) { | |
const number = yield lookup(name, phonebook); | |
const reg = yield lookup(number, govDb); | |
return lookup(reg, taxDb); | |
}); | |
console.log('Searching for "schristo": ' + taxCodeLookup('schristo').getOrElse('Not found')); | |
console.log('Searching for "_schristo": ' + taxCodeLookup('_schristo').getOrElse('Not found')); |
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
const | |
genDo = require('./gen-do'), | |
Promise = require('fantasy-promises'), | |
delay = (n, v) => | |
new Promise(resolve => setTimeout(() => resolve(v), n)), | |
afterDelay = genDo(function*(v1, v2) { | |
console.log('waiting for v1'); | |
const _v1 = yield delay(500, v1); | |
console.log('got: ' + _v1); | |
console.log('waiting for v2'); | |
const _v2 = yield delay(500, v2); | |
console.log('got: ' + _v2); | |
return Promise.of(_v1 + " " + v2); | |
}); | |
afterDelay("Hello", "World!").fork(str => console.log(str)); |
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
const | |
genDo = require('./gen-do'), | |
StateT = require('fantasy-states').StateT, | |
IO = require('fantasy-io'), | |
fs = require('fs'), | |
M = StateT(IO), | |
prependTo = (a) => (b) => b + a, | |
readFile = (f) => IO(() => fs.readFileSync(f, 'utf8')), | |
println = (s) => IO(() => console.log(s)), | |
program = genDo(function*(f1, f2) { | |
const f1Str = yield M.lift(readFile(f1)); | |
yield M.modify(prependTo(f1Str)); | |
const f2Str = yield M.lift(readFile(f2)); | |
yield M.modify(prependTo(f2Str)); | |
const state = yield M.get; | |
return M.lift(println(state)); | |
}); | |
program('gen-do.js', 'state-io-example.js').exec('').unsafePerform(); |
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
const | |
genDo = require('./gen-do'), | |
StateT = require('fantasy-states').StateT, | |
Promise = require('fantasy-promises'), | |
M = StateT(Promise), | |
question = () => | |
Promise.of('What is the answer to Life, the Universe and Everything?'), | |
deepThought = () => new Promise(function(resolve) { | |
const sevenAndAHalfMillionYears = 7500000; | |
setTimeout(resolve, sevenAndAHalfMillionYears / 10000, 42); | |
}), | |
prependTo = (a) => (b) => b + ' ' + a, | |
prog = genDo(function*() { | |
const q1 = yield M.lift(question()); | |
yield M.modify(prependTo(q1)); | |
const q2 = yield M.lift(deepThought()); | |
yield M.modify(prependTo(q2)); | |
return M.get; | |
}); | |
prog().exec('>').fork(x => console.log(x)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The function exported from
gen-do.js
accepts a generator that yields monads implementing the Fantasy-Land Monad Spec.This allows for composing monads in an imperative-like form, similar to Haskell's "do" notation, such as the following Option Monad example from
option-example.js
: