Skip to content

Instantly share code, notes, and snippets.

@ValeTheVioletMote
Created January 10, 2020 20:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ValeTheVioletMote/c821a4851ac5ce025a52781ba1346b01 to your computer and use it in GitHub Desktop.
Save ValeTheVioletMote/c821a4851ac5ce025a52781ba1346b01 to your computer and use it in GitHub Desktop.
Minor FP & Railway
const _nudef = x => typeof x == 'undefined' || x == null || x == undefined;
const coalesce = (...vals) => vals.find((v,i)=>_nudef(v) == false || i==vals.length);
const u_pipe = (...fns) => (x) => fns.reduce((prev, func) => func(prev), x);
const None = Object.freeze({monad_name: "None", is: function is_none(x) {return x==this;}});
const build_monad = monad_name => {
var mon = (monad_name => {
return val => {
// Unpack if a packed monad
if(typeof val == "function" && val.monad_name == monad_name){
return val();
}
// Otherwise, pack the monad
var x = val;
var monad = () => x;
Object.defineProperty(monad, "monad_name", {value: monad_name});
return monad;
};
})(monad_name);
Object.defineProperty(mon, "is", {value: unk => typeof unk == "function" && unk.monad_name == monad_name});
Object.defineProperty(mon, "monad_name", {value: monad_name});
return mon;
};
const Some = build_monad("Some");
const Maybe = x => (!_nudef(x)) ? Some(x) : None;
Object.defineProperty(Maybe, 'check', {value: x => _nudef(x) ? None : Some});
Object.defineProperty(Maybe, "match", {value: function match_some(maybe) {
switch([Some.is(maybe),maybe==None].join(",")){
case "true,false":
return Some;
break;
case "false,true":
return None;
break;
default:
throw `Attempted Maybe match on neither Some nor None`;
}
}});
const build_choice = (choice_name, choices=[]) => {
return possible_option => {
var p = Maybe(choices.find(choice => choice.is(possible_option)));
switch (Maybe.match(p)) {
case Some:
p = Some(p);
return p;
break;
case None:
throw `${coalesce(possible_option.monad_name, possible_option.constructor.name, possible_option)} is not a choice for ${choice_name}! Valid choices are:\n${choices.map(c=>c.monad_name).join("\n")}`;
break;
}
};
};
const Success = build_monad("Success");
const Failure = build_monad("Failure");
const Either = build_choice("Either", [Success, Failure]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment