Skip to content

Instantly share code, notes, and snippets.

@steenhansen
Last active February 24, 2022 06:37
Show Gist options
  • Save steenhansen/bea78d92ab4fd508f8c2292e68197144 to your computer and use it in GitHub Desktop.
Save steenhansen/bea78d92ab4fd508f8c2292e68197144 to your computer and use it in GitHub Desktop.
/**
* Custom Maybe Monad used in FP in JS book written in ES6
* Author: Luis Atencio
* https://github.com/luijar/functional-programming-js/blob/master/src/model/monad/Maybe.js
*/
class Maybe {
static just(a) { return new Just(a); }
static nothing() { return new Nothing(); }
static fromNullable(a) { return (a !== null && a !== undefined) ? Maybe.just(a) : Maybe.nothing(); }
static of(a) { return Maybe.just(a); }
get isNothing() { return false; }
get isJust() { return false; } };
class Just extends Maybe {
constructor(value) { super(); this._value = value; }
get value() { return this._value; }
map(f) { return Maybe.fromNullable(f(this._value)); }
chain(f) { return f(this._value); }
getOrElse() { return this._value; }
filter(f) { Maybe.fromNullable(f(this._value) ? this._value : null); }
get isJust() { return true; }
toString () { return `Maybe.Just(${this._value})`; } };
class Nothing extends Maybe {
map(f) { return this; }
chain(f) { return this; }
get value() { throw new TypeError("Can't extract the value of a Nothing."); }
getOrElse(other) { return other; }
filter() { return this._value; }
get isNothing() { return true; }
toString() { return 'Maybe.Nothing'; } };
const getProp = key_name => an_object => an_object[key_name];
const maybeMiddleName = (a_person) => {
const middle_name = Maybe.fromNullable(a_person)
.map(getProp('person'))
.map(getProp('address'))
.map(getProp('name'))
.map(getProp('middle'))
.getOrElse('No-Middle-Name');
return middle_name; }
///////////////////////////////////////////////////////////////////////////
var no_middle = {person : { address: { name: {first: 'Abraham', last:'Lincoln'}}}};
var no_name = {person : { address: { moniker: {first: 'Abraham', last:'Lincoln'}}}};
var no_address = {person : { info: { name: {first: 'Abraham', last:'Lincoln'}}}};
var no_person = {human : { address: { name: {first: 'Abraham', last:'Lincoln'}}}};
var empty_object = {};
var no_object = [];
var null_val = null;
var has_middle = {person : { address: { name: {first: 'Abraham', middle:'The Best', last:'Lincoln'}}}};
var the_people = [no_middle, no_name, no_address, no_person, empty_object, no_object, null_val, has_middle];
the_middles = the_people.map(a_person=> maybeMiddleName(a_person));
console.dir(the_middles);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment