Created
September 15, 2020 22:29
-
-
Save tanglebones/695f4d60b1cc3263411b709a9f1e74d5 to your computer and use it in GitHub Desktop.
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
(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