Skip to content

Instantly share code, notes, and snippets.

@pfgray
Created October 2, 2018 13:32
Show Gist options
  • Save pfgray/7a38d94658e09a724643a9065b755b6c to your computer and use it in GitHub Desktop.
Save pfgray/7a38d94658e09a724643a9065b755b6c to your computer and use it in GitHub Desktop.
/**
* This method sequences an array of Monads, chaining each one into the next.
* The result will be one Monad of a list of each unwrapped value.
*/
function sequenceM(Type) {
return ms => {
function doIt(mArr, restMs) {
if(restMs.length === 0) {
return mArr;
} else {
const [m, ...moreMs] = restMs;
return mArr['fantasy-land/chain'](as => {
return doIt(m['fantasy-land/map'](aPrime => [...as, aPrime]), moreMs);
});
}
}
return doIt(Type['fantasy-land/of']([]), ms);
}
}
/**
* Maybe from https://evilsoft.github.io/crocks
*/
const Maybe = require('crocks/src/Maybe');
console.log(sequenceM(Maybe)([
Maybe.Just(5),
Maybe.Just(3),
Maybe.Just(6),
Maybe.Just({foo: 'bar'}),
])) // Just [ 5, 3, 6, { foo: "bar" } ]
console.log(sequenceM(Maybe)([
Maybe.Just(5),
Maybe.Just(3),
Maybe.Nothing(),
Maybe.Just({foo: 'bar'}),
])) // Nothing
/**
* Async from https://evilsoft.github.io/crocks
*/
const Async = require('crocks/src/Async');
const delay = ms => x => Async((rej, res) => setTimeout(() => res(x), ms));
const delaySecond = delay(1000);
const subject =
sequenceM(Async)([
delaySecond('a'),
delaySecond('b'),
delaySecond('c'),
delaySecond('d'),
delaySecond('e'),
]).fork(() => {}, console.log) // logs [ 'a', 'b', 'c', 'd', 'e' ] after 5 seconds
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment