Skip to content

Instantly share code, notes, and snippets.

@neurosnap
Last active September 21, 2018 21:04
Show Gist options
  • Save neurosnap/632402fb5d3becd0c8ca509d5b83cd5b to your computer and use it in GitHub Desktop.
Save neurosnap/632402fb5d3becd0c8ca509d5b83cd5b to your computer and use it in GitHub Desktop.
const RESULT = "RESULT";
const isResult = obj => obj && obj.type === RESULT;
const Result = value => ({
type: RESULT,
value
});
const NOTHING = "NOTHING";
const isNothing = obj => obj && obj.type === NOTHING;
const Nothing = value => ({
type: NOTHING,
value
});
function maybe(result) {
if (isResult(result) || isNothing(result)) {
return result;
}
if (result === undefined || result === null) {
return Nothing(result);
}
return Result(result);
}
function lift(fn) {
if (typeof fn !== "function") {
return () => maybe(fn);
}
return (...args) => {
const result = fn(...args);
return maybe(result);
};
}
const bind = (...fns) => init =>
fns.reduce((prevResult, fn) => {
if (isNothing(prevResult)) {
return prevResult;
}
return fn(prevResult.value);
}, init());
// playground
const add = val => val + 1;
const double = val => val * 2;
const monadResult = bind(lift(add), lift(double));
console.log(monadResult(lift(2)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment