Skip to content

Instantly share code, notes, and snippets.

@Ficik
Created October 10, 2017 00:11
Show Gist options
  • Select an option

  • Save Ficik/68c5e0851a402cf2d8b27c82008681c4 to your computer and use it in GitHub Desktop.

Select an option

Save Ficik/68c5e0851a402cf2d8b27c82008681c4 to your computer and use it in GitHub Desktop.
Maybe monad
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