Skip to content

Instantly share code, notes, and snippets.

@gabejohnson
Last active June 9, 2017 15:58
Show Gist options
  • Save gabejohnson/406028a7eb78c258cd025cc82e718dc4 to your computer and use it in GitHub Desktop.
Save gabejohnson/406028a7eb78c258cd025cc82e718dc4 to your computer and use it in GitHub Desktop.
Some tuple implementations
function Unit() { return Unit; }
function Pair(fst, snd) {
'use strict';
if(this === void 0) return new Pair(fst, snd);
this.fst = fst;
this.snd = snd;
}
Pair.prototype.map = //...
//...
function Identity(x) {
'use strict';
if(this === void 0) return new Identity(x);
Pair.call(this, x, Unit);
}
Identity.prototype = Object.create(Identity.prototype);
Identity.prototype.constructor = Identity;
function Triple(e1, e2, e3) {
'use strict';
if(this === void 0) return new Triple(e1, e2, e3);
Pair.call(this, e1, Pair(e2, Identity(e3)));
}
Triple.prototype = Object.create(Pair.prototype);
Triple.prototype.constructor = Triple;
//...
const makeTupleType = (n, name, methods, statics) => {
const type = (0, (...args) => Object.assign(f => f(...args), {
constructor: type
}, methods));
type['@@type'] = name;
return Object.assign(type, statics);
}
const Pair = makeTupleType(2, 'Pair', {
map(f) {
let values = this((...args) => args);
const last = values[values.length-1];
values = values.slice(0, values.length-1).concat([f(last)]);
return Pair.apply(null, values);
}
}, { of(a) { return Pair(a,a); }})
// ...
// Arguments based tuple
function Tuple() {
if (arguments.length === 0) return Unit;
var itr = arguments[Symbol.iterator]();
var args = {[Symbol.iterator]: function value() { return itr; }};
for (var k in arguments) args[parseInt(k)+1] = arguments[k];
return args;
}
// no constructors
const _pair = fst => ({
of: snd => ({
fst,
snd,
map: f => _pair(fst).of(snd),
ap: f => _pair(fst).of(f(snd)),
chain: f => {
const result = f(snd);
return _pair(fst.concat(result.fst)).of(result.snd);
},
extract: () => snd,
[Symbol.iterator]: function *() {
yield fst;
yield snd;
}
})
});
const pair = (...ab) => ab.length === 1 ? _pair(ab[0]) : _pair(ab[0]).of(ab[1]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment