Skip to content

Instantly share code, notes, and snippets.

@MiracleBlue
Created March 31, 2018 22:31
Show Gist options
  • Save MiracleBlue/498a33a356cabfc5026178c60eee0323 to your computer and use it in GitHub Desktop.
Save MiracleBlue/498a33a356cabfc5026178c60eee0323 to your computer and use it in GitHub Desktop.
My own implementation of a Maybe monad :)
import {
reduce,
complement,
isNil
} from 'ramda';
const isDefined = complement(isNil);
const Maybe = do {
const __maybe = Symbol('Maybe');
const __just = Symbol('Maybe.Just');
const __nothing = Symbol('Maybe.Nothing');
const isMaybe = value => isDefined(value) && isDefined(value[__maybe]);
const isJust = value => isMaybe(value) && value[__maybe] === __just;
const isNothing = value => isMaybe(value) && value[__maybe] === __nothing;
const maybeOf = value => {
if (!isDefined(value)) return Maybe.Nothing();
if (!isMaybe(value)) return Maybe.Just(value);
return value;
};
const justMap = (value) => (handlerFn) => Maybe.Just(handlerFn(value));
const justBind = (value) => (handlerFn) => maybeOf(handlerFn(value));
const justFold = (value) => (handleJust) => handleJust(value);
const nothingFold = () => (unused, handleNothing) => handleNothing();
const unwrap = (monad) => monad[__just]; // DANGEREUX
// Lets get this thing out of this do block!
({
// ...withFunctor,
isMaybe,
isJust,
isNothing,
of: maybeOf,
Nothing: () => ({
[__maybe]: __nothing,
map: () => Maybe.Nothing(),
bind: () => Maybe.Nothing(),
flatMap: () => Maybe.Nothing(),
fold: (handleJust, handleNothing) => handleNothing(),
ifJust: () => Maybe.Nothing(),
ifNothing: (handler) => handler(),
orElse: (elseValue) => elseValue
}),
Just: value => ({
[__maybe]: __just,
[__just]: value,
map: justMap(value),
bind: justBind(value),
flatMap: justBind(value),
fold: justFold(value),
ifJust: (handler) => handler(value),
ifNothing: () => Maybe.Just(value),
orElse: () => value
})
});
}
export default Maybe;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment