Created
January 10, 2020 20:24
-
-
Save ValeTheVioletMote/c821a4851ac5ce025a52781ba1346b01 to your computer and use it in GitHub Desktop.
Minor FP & Railway
This file contains 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 _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