Skip to content

Instantly share code, notes, and snippets.

@tanglebones
Created September 15, 2020 22:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanglebones/695f4d60b1cc3263411b709a9f1e74d5 to your computer and use it in GitHub Desktop.
Save tanglebones/695f4d60b1cc3263411b709a9f1e74d5 to your computer and use it in GitHub Desktop.
(function() {
// using `value =>` makes value the 'this' of the functions below
const MaybeMonad = value => ({
value,
flatMap(f) {
// The point of the maybe is to prevent problems.
// Having a "nothing value" indicates a problem, so we short circuit
// the return.
// This is like SQL NULL in that any operation on nothing
// returns nothing.
if (this === MaybeMonad.nothing) { // using a special value here so null and undefined can be used in return values as well
return this;
}
// otherwise apply the function on the wrapped value
return f(value);
},
map(f) {
// lift a function f that acts on values into acting on the Monad of the values
return this.flatMap(value => MaybeMonad.of(f(value)));
},
unwrap() {
// handle the 'nothing case'
// normally the calling code should compare against MaybeMonad.nothing
// to avoid calling unwrap on nothing.
if (this === MaybeMonad.nothing) {
return NaN; // could also throw if the caller is expected to behave.
}
// handle the value case
return this.value;
},
});
// abuse that a function can have other props to hold "top level" functions
// for the MaybeMonad
MaybeMonad.of = a => MaybeMonad(a);
MaybeMonad.nothing = MaybeMonad.of(Symbol('Nothing'));
// divide :: a -> a -> MaybeMonad<a>
const divide = by => value => {
// Can't divide by 0, some have tried but not with a lot of success
if (by === 0) {
return MaybeMonad.nothing;
}
return MaybeMonad.of(value/by);
};
// log :: a -> a
const log = value => { console.log(value); return value; };
console.log(MaybeMonad.of(100).flatMap(divide(2)).map(log).flatMap(divide(3)).map(log).unwrap());
console.log("With a /0:");
console.log(MaybeMonad.of(100).flatMap(divide(0)).map(log).flatMap(divide(3)).map(log).unwrap());
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment