Last active
December 17, 2015 20:09
-
-
Save markandrus/5665384 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| 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