Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 26 additions & 24 deletions id.js
Original file line number Diff line number Diff line change
@@ -1,81 +1,83 @@
var fl = require('./')
'use strict';

function Id(a) {
this.value = a;
}
const fl = require('./');

const Id = function Id(a) {
this.value = a;
};

// Setoid
Id.prototype[fl.equals] = function(b) {
return typeof this.value[fl.equals] === "function" ? this.value[fl.equals](b.value) : this.value === b.value;
return typeof this.value[fl.equals] === 'function' ? this.value[fl.equals](b.value) : this.value === b.value;
};

// Semigroup (value must also be a Semigroup)
Id.prototype[fl.concat] = function(b) {
return new Id(this.value[fl.concat](b.value));
return new Id(this.value[fl.concat](b.value));
};

// Monoid (value must also be a Monoid)
Id[fl.empty] = function() {
return new Id(this.value[fl.empty] ? this.value[fl.empty]() : this.value.constructor[fl.empty]());
return new Id(this.value[fl.empty] ? this.value[fl.empty]() : this.value.constructor[fl.empty]());
};
Id.prototype[fl.empty] = Id[fl.empty];

// Foldable
Id.prototype[fl.reduce] = function(f, acc) {
return f(acc, this.value);
return f(acc, this.value);
};

Id.prototype.toArray = function() {
return [this.value];
return [this.value];
};

// Functor
Id.prototype[fl.map] = function(f) {
return new Id(f(this.value));
return new Id(f(this.value));
};

// Apply
Id.prototype[fl.ap] = function(b) {
return new Id(b.value(this.value));
return new Id(b.value(this.value));
};

// Traversable
Id.prototype[fl.traverse] = function(f, of) {
// the of argument is only provided for types where map might fail.
return f(this.value)[fl.map](Id[fl.of]);
// the of argument is only provided for types where map might fail.
return f(this.value)[fl.map](Id[fl.of]);
};

// Chain
Id.prototype[fl.chain] = function(f) {
return f(this.value);
return f(this.value);
};

// ChainRec
Id[fl.chainRec] = function(f, i) {
var state = { done: false, value: i};
var next = (v) => ({ done: false, value: v });
var done = (v) => ({ done: true, value: v });
while (state.done === false) {
state = f(next, done, state.value).value;
}
return new Id(state.value);
const next = v => ({done: false, value: v});
const done = v => ({done: true, value: v});
let state = {done: false, value: i};
while (state.done === false) {
state = f(next, done, state.value).value;
}
return new Id(state.value);
};
Id.prototype[fl.chainRec] = Id[fl.chainRec];

// Extend
Id.prototype[fl.extend] = function(f) {
return new Id(f(this));
return new Id(f(this));
};

// Applicative
Id[fl.of] = function(a) {
return new Id(a);
return new Id(a);
};
Id.prototype[fl.of] = Id[fl.of];

// Comonad
Id.prototype[fl.extract] = function() {
return this.value;
return this.value;
};

module.exports = Id;
74 changes: 37 additions & 37 deletions id_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,94 +21,94 @@ const Id = require('./id');

// Special type of sum for the type of string.
const Sum = tagged('v');
Sum[of] = (x) => Sum(x);
Sum[of] = Sum;
Sum[empty] = () => Sum('');
Sum.prototype[of] = Sum[of];
Sum.prototype[empty] = Sum[empty];
Sum.prototype[map] = function(f) {
return Sum(f(this.v));
return Sum(f(this.v));
};
Sum.prototype[concat] = function(x) {
return Sum(this.v + x.v);
return Sum(this.v + x.v);
};
Sum.prototype[equals] = function(x) {
return this.v[equals] ? this.v[equals](x.v) : this.v === x.v;
return this.v[equals] ? this.v[equals](x.v) : this.v === x.v;
};

const equality = (x, y) => x[equals] ? x[equals](y) : x === y;
const test = f => t => {
t.ok(f("x"));
t.done();
t.ok(f('x'));
t.done();
};

exports.applicative = {
identity: test((x) => applicative.identity(Id)(equality)(x)),
homomorphism: test((x) => applicative.homomorphism(Id)(equality)(x)),
interchange: test((x) => applicative.interchange(Id)(equality)(x))
identity: test(x => applicative.identity(Id)(equality)(x)),
homomorphism: test(x => applicative.homomorphism(Id)(equality)(x)),
interchange: test(x => applicative.interchange(Id)(equality)(x)),
};

exports.apply = {
composition: test((x) => apply.composition(Id)(equality)(x))
composition: test(x => apply.composition(Id)(equality)(x)),
};

exports.chain = {
associativity: test((x) => chain.associativity(Id)(equality)(x))
associativity: test(x => chain.associativity(Id)(equality)(x)),
};

exports.chainRec = {
equivalence: test((x) => {
var predicate = a => a.length > 5
var done = Id[of]
var next = a => Id[of](a[concat]([x]))
var initial = [x]
return chainRec.equivalence(Id)(equality)(predicate)(done)(next)(initial)
})
equivalence: test(x => {
const predicate = a => a.length > 5;
const done = Id[of];
const next = a => Id[of](a[concat]([x]));
const initial = [x];
return chainRec.equivalence(Id)(equality)(predicate)(done)(next)(initial);
}),
};

exports.comonad = {
leftIdentity: test((x) => comonad.leftIdentity(Id[of])(equality)(x)),
rightIdentity: test((x) => comonad.rightIdentity(Id[of])(equality)(x)),
associativity: test((x) => comonad.associativity(Id[of])(equality)(x))
leftIdentity: test(x => comonad.leftIdentity(Id[of])(equality)(x)),
rightIdentity: test(x => comonad.rightIdentity(Id[of])(equality)(x)),
associativity: test(x => comonad.associativity(Id[of])(equality)(x)),
};

exports.extend = {
associativity: test((x) => extend.associativity(Id[of])(equality)(x))
associativity: test(x => extend.associativity(Id[of])(equality)(x)),
};

exports.foldable = {
associativity: test((x) => foldable.associativity(Id[of])(equality)(x))
associativity: test(x => foldable.associativity(Id[of])(equality)(x)),
};

exports.functor = {
identity: test((x) => functor.identity(Id[of])(equality)(x)),
composition: test((x) => functor.composition(Id[of])(equality)(x))
identity: test(x => functor.identity(Id[of])(equality)(x)),
composition: test(x => functor.composition(Id[of])(equality)(x)),
};

exports.monad = {
leftIdentity: test((x) => monad.leftIdentity(Id)(equality)(x)),
rightIdentity: test((x) => monad.rightIdentity(Id)(equality)(x))
leftIdentity: test(x => monad.leftIdentity(Id)(equality)(x)),
rightIdentity: test(x => monad.rightIdentity(Id)(equality)(x)),
};

exports.monoid = {
leftIdentity: test((x) => monoid.leftIdentity(Id[of](Sum[empty]()))(equality)(Sum[of](x))),
rightIdentity: test((x) => monoid.rightIdentity(Id[of](Sum[empty]()))(equality)(Sum[of](x)))
leftIdentity: test(x => monoid.leftIdentity(Id[of](Sum[empty]()))(equality)(Sum[of](x))),
rightIdentity: test(x => monoid.rightIdentity(Id[of](Sum[empty]()))(equality)(Sum[of](x))),
};

// Semigroup tests are broken otherwise for this.
String.prototype[concat] = String.prototype.concat
String.prototype[concat] = String.prototype.concat;

exports.semigroup = {
associativity: test((x) => semigroup.associativity(Id[of])(equality)(x))
associativity: test(x => semigroup.associativity(Id[of])(equality)(x)),
};

exports.setoid = {
reflexivity: test((x) => setoid.reflexivity(Id[of])(equality)(x)),
symmetry: test((x) => setoid.symmetry(Id[of])(equality)(x)),
transitivity: test((x) => setoid.transitivity(Id[of])(equality)(x))
reflexivity: test(x => setoid.reflexivity(Id[of])(equality)(x)),
symmetry: test(x => setoid.symmetry(Id[of])(equality)(x)),
transitivity: test(x => setoid.transitivity(Id[of])(equality)(x)),
};

exports.traversable = {
naturality: test((x) => traversable.naturality(Id[of])(equality)(Id[of](x))),
identity: test((x) => traversable.identity(Id[of])(equality)(x)),
composition: test((x) => traversable.composition(Id[of])(equality)(Id[of](Sum[of](x))))
naturality: test(x => traversable.naturality(Id[of])(equality)(Id[of](x))),
identity: test(x => traversable.identity(Id[of])(equality)(x)),
composition: test(x => traversable.composition(Id[of])(equality)(Id[of](Sum[of](x)))),
};
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

'use strict';

/* eslint comma-dangle: ["off"], no-var: ["off"], strict: ["error", "function"] */
/* global self */

var mapping = {
equals: 'fantasy-land/equals',
concat: 'fantasy-land/concat',
Expand Down
25 changes: 11 additions & 14 deletions laws/applicative.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,23 @@ const {of, ap} = require('..');
**/

const identityʹ = t => eq => x => {
const a = t[of](x)[ap](t[of](identity));
const b = t[of](x);
return eq(a, b);
const a = t[of](x)[ap](t[of](identity));
const b = t[of](x);
return eq(a, b);
};

const homomorphism = t => eq => x => {
const a = t[of](x)[ap](t[of](identity));
const b = t[of](identity(x));
return eq(a, b);
const a = t[of](x)[ap](t[of](identity));
const b = t[of](identity(x));
return eq(a, b);
};

const interchange = t => eq => x => {
const u = t[of](identity);
const u = t[of](identity);

const a = t[of](x)[ap](u);
const b = u[ap](t[of](thrush(x)));
return eq(a, b);
const a = t[of](x)[ap](u);
const b = u[ap](t[of](thrush(x)));
return eq(a, b);
};

module.exports = { identity: identityʹ
, homomorphism
, interchange
};
module.exports = {identity: identityʹ, homomorphism, interchange};
10 changes: 5 additions & 5 deletions laws/apply.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ const {of, map, ap} = require('..');
**/

const composition = t => eq => x => {
const y = t[of](identity);
const y = t[of](identity);

const a = y[ap](y[ap](y[map](compose)));
const b = y[ap](y)[ap](y);
return eq(a, b);
const a = y[ap](y[ap](y[map](compose)));
const b = y[ap](y)[ap](y);
return eq(a, b);
};

module.exports = { composition };
module.exports = {composition};
16 changes: 7 additions & 9 deletions laws/bifunctor.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@ const {bimap} = require('..');
**/

const identityʹ = t => eq => x => {
const a = t(x)[bimap](identity, identity);
const b = t(x);
return eq(a, b);
const a = t(x)[bimap](identity, identity);
const b = t(x);
return eq(a, b);
};

const composition = t => eq => x => {
const a = t(x)[bimap](compose(identity)(identity), compose(identity)(identity));
const b = t(x)[bimap](identity, identity)[bimap](identity, identity);
return eq(a, b);
const a = t(x)[bimap](compose(identity)(identity), compose(identity)(identity));
const b = t(x)[bimap](identity, identity)[bimap](identity, identity);
return eq(a, b);
};

modules.exports = { identity: identityʹ
, composition
};
module.exports = {identity: identityʹ, composition};
8 changes: 4 additions & 4 deletions laws/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ const {of, chain} = require('..');
**/

const associativity = t => eq => x => {
const a = t[of](x)[chain](t[of])[chain](t[of]);
const b = t[of](x)[chain]((x) => t[of](x)[chain](t[of]));
return eq(a, b);
const a = t[of](x)[chain](t[of])[chain](t[of]);
const b = t[of](x)[chain](x => t[of](x)[chain](t[of]));
return eq(a, b);
};

module.exports = { associativity };
module.exports = {associativity};
10 changes: 4 additions & 6 deletions laws/chainrec.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'use strict';

const {identity} = require('fantasy-combinators');
const {chain, map, chainRec} = require('..');


/**

### ChainRec
Expand All @@ -15,9 +13,9 @@ const {chain, map, chainRec} = require('..');
**/

const equivalence = t => eq => p => d => n => x => {
const a = t[chainRec]((next, done, v) => p(v) ? d(v)[map](done) : n(v)[map](next), x);
const b = (function step(v) { return p(v) ? d(v) : n(v)[chain](step); }(x));
return eq(a, b);
const a = t[chainRec]((next, done, v) => p(v) ? d(v)[map](done) : n(v)[map](next), x);
const b = (function step(v) { return p(v) ? d(v) : n(v)[chain](step); }(x));
return eq(a, b);
};

module.exports = { equivalence };
module.exports = {equivalence};
Loading