Created
October 10, 2017 00:11
-
-
Save Ficik/68c5e0851a402cf2d8b27c82008681c4 to your computer and use it in GitHub Desktop.
Maybe monad
This file contains hidden or 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 GenericMaybe = isNothing => { | |
| const Nothing = value => { | |
| const self = _ => self; | |
| return self; | |
| } | |
| const Just = value => (fn, ...tail) => tail.length > 0 ? Maybe.from(fn(value))(...tail) : Maybe.from(fn(value)) | |
| const log = (value, resolve) => (...args) => console.log(...args, value) || resolve; | |
| const Maybe = fn => value => Maybe.from(fn(value)) | |
| Maybe.from = value => { | |
| if (typeof(value) === 'function' && value.isMaybe){ | |
| return value; | |
| } | |
| const valueIsNothing = isNothing(value); | |
| const resolve = valueIsNothing ? Nothing(value) : Just(value); | |
| resolve.unwrap = valueIsNothing ? undefined : value; | |
| resolve.isNothing = !!valueIsNothing; | |
| resolve.isJust = !valueIsNothing; | |
| resolve.isMaybe = true; | |
| resolve.log = log(value, resolve); | |
| return resolve; | |
| } | |
| return Maybe; | |
| } | |
| const Maybe = GenericMaybe(value => value === NaN || value === null || value === undefined) | |
| const MaybeNumber = GenericMaybe(value => typeof(value) !== 'number' || !isFinite(value)) | |
| const MaybeString = GenericMaybe(value => typeof(value) !== 'string') | |
| // | |
| console.log( | |
| Maybe.from(null).isNothing === true, // can check for nothing | |
| Maybe.from(1).isJust === true, // can check for just | |
| Maybe.from("foo").unwrap === "foo", // Maybe can be unwrapped | |
| Maybe.from(null).unwrap === undefined, // unwrapped nothings is undefined | |
| Maybe.from(null)(x => x*2).isNothing === true, // nothings doesnt invoke functions | |
| Maybe.from(2)(x => x*2).isJust === true, // just does | |
| MaybeNumber.from(0)(x => x/0).isNothing === true, // finite and actual numbers only | |
| MaybeNumber.from(10)(x => x/0).isNothing === true, | |
| MaybeString.from("foo")(x => null).isNothing === true, // can return null any time | |
| MaybeString.from("foo")(x => x.split('')).isNothing === true, // string type checking | |
| MaybeString.from("2.0")(x => "3" + x, MaybeNumber(parseFloat)).unwrap === 32, // string to number casting | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment