Skip to content

Instantly share code, notes, and snippets.

@rjchatfield
Created February 1, 2015 13:52
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rjchatfield/54393388f80f55fcc81a to your computer and use it in GitHub Desktop.
Save rjchatfield/54393388f80f55fcc81a to your computer and use it in GitHub Desktop.
Maybe, Either & Try Functors in ES6
//--
//-- FUNCTORS in ES6
//--
//-- BOILER PLATE
let fmap = (f) => (functor) => functor.map(f);
let c2 = (f2, f1) => (x) => f2(f1(x));
let c3 = (f3, f2, f1) => (x) => f3(f2(f1(x)));
let add1 = (x) => x + 1;
let dbl = (x) => x + x;
let identity = (x) => x;
let thrower = (x) => {
throw "Thrower do what it do";
}
// app:: (functor) -> functor
let app = c2(fmap(add1), fmap(dbl));
// run:: (functor) -> ()
let run = (functor) => console.log( app(functor) );
//--
//-- FUNCTOR
//--
class _Functor {
constructor(val) {
this.val = val;
}
map(f) {
return new _Functor(f(this.val));
}
}
//--
//-- MAYBE
//--
class _Maybe extends _Functor {
map(f) {
if (this.val) {
return new _Maybe(f(this.val));
}
else {
return new _Maybe();
}
}
}
let Maybe = (v) => new _Maybe(v);
run( Maybe(1) ); // <- _Maybe {val: 3}
run( Maybe() ); // <- _Maybe {val: undefined}
//--
//-- EITHER
//--
class _Either extends _Functor {
constructor(left, right) {
if (right) {
super(right);
}
else {
super(left);
}
}
}
let Either = (l, r) => new _Either(l, r);
run( Either(1) ); // <- _Functor {val: 3}
run( Either(1, 2) ); // <- _Functor {val: 5}
//--
//-- TRY
//--
class _Try {
constructor(f, val) {
try {
this.val = f(val);
}
catch(e) {
this.err = e;
}
}
map(f) {
if (this.err) {
return this;
}
else {
return new _Try(f, this.val);
}
}
}
let Try = (f, x) => new _Try(f, x);
run( Try(identity, 1) ); // <- _Maybe {val: 3}
run( Try(thrower, 1) ); // <- _Maybe {err: "Thrower do what it do"}
//--
//-- ALL DONE
//--
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment