Skip to content

Instantly share code, notes, and snippets.

@markandrus
Last active December 17, 2015 20:09
Show Gist options
  • Select an option

  • Save markandrus/5665384 to your computer and use it in GitHub Desktop.

Select an option

Save markandrus/5665384 to your computer and use it in GitHub Desktop.
var m = require('continuable-fantasy'),
ma = m.of('Hello world'),
me = m.error(new Error('Some error'));
/*fs = require('fs'),
ma = m(fs.readFile.bind(null, __filename)).map(function(a) {
return a.toString();
});*/
function check(l, r) {
var succs = [], errs = [], n = 2;
function callback(q) {
return function(a) {
q.push(a.toString());
if (--n === 0) {
if (!( succs.length === 2
&& errs.length === 0
&& succs[0] === succs[1]
|| succs.length === 0
&& errs.length === 2
&& errs[0] === errs[1] ))
throw new Error('Refuted!');
/*if (succs.length === 2)
console.log(succs.join(' ≡ '));
else
console.log(errs.join(' ≡ '));*/
}
}
}
l.consume(callback(errs), callback(succs));
r.consume(callback(errs), callback(succs));
}
function tuplesFrom() {
var vs = arguments, ts = [],
t = Array.prototype.map.call(arguments, function() { return 0; });
n = Array.prototype.reduce.call(arguments, function(a, bs) {
return a * bs.length;
}, 1);
function nextTuple(t) {
for (var i=0; i<t.length; i++)
if (++t[i] < vs[i].length)
break;
else
t[i] = 0;
return t;
}
function toTuple(t) {
return t.map(function(i, j) {
return vs[j][i];
});
}
for (var i=0; i<n; i++)
ts.push(toTuple(nextTuple(t).slice(0)));
return ts;
}
// Inputs
// ------
var mas = [ma, me];
// fa :: a -> m a
function fa(a) {
return m.of(a.toUpperCase());
}
// fe :: a -> m a
function fe(a) {
return m.error(new Error(a));
}
var fs = [fa, fe];
// ga :: a -> m a
function ga(a) {
return m.of(a.slice(1));
}
// ga :: a -> m a
function ge(_) {
return m.error('Another error');
}
var gs = [ga, ge];
// b2c :: b -> c
function b2c(b) {
return b ? 1 : 0;
}
// a2b :: a -> b
function a2b(a) {
return a.length === 0;
}
// Laws
// ----
// Identity (Functor)
tuplesFrom(mas).forEach(function(tuple) {
var ma = tuple[0];
check(
ma.map(function(a) { return a; }),
ma
);
});
// Composition (Functor)
tuplesFrom([m], [b2c], [a2b]).forEach(function(tuple) {
var m = tuple[0], f = tuple[1], g = tuple[2];
check(
ma.map(function(a) { return f(g(a)); }),
ma.map(g).map(f)
);
});
// Associativity (Chain)
tuplesFrom(mas, fs, gs).forEach(function(tuple) {
var ma = tuple[0], f = tuple[1], g = tuple[2];
check(
ma.chain(f).chain(g),
ma.chain(function(a) { return f(a).chain(g); })
);
});
// Left Identity (Monad)
tuplesFrom(['Hello world'], [m], fs).forEach(function(tuple) {
var a = tuple[0], m = tuple[1], f = tuple[2];
check(
m.of(a).chain(f),
f(a)
);
});
// Right Identity (Monad)
tuplesFrom([m], mas).forEach(function(tuple) {
var m = tuple[0], ma = tuple[1];
check(
ma.chain(m.of),
ma
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment