ramda-fantasy
Advanced tools
Comparing version 0.3.0 to 0.4.0
@@ -16,3 +16,3 @@ { | ||
"description": "Fantasy Land compatible types for easy integration with Ramda", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"homepage": "https://www.github.com/ramda/ramda-fantasy", | ||
@@ -34,3 +34,3 @@ "license": "MIT", | ||
"dependencies": { | ||
"ramda": "^0.15.0" | ||
"ramda": ">=0.15.0 <0.18.0" | ||
}, | ||
@@ -37,0 +37,0 @@ "devDependencies": { |
@@ -11,4 +11,4 @@ ramda-fantasy | ||
## Project status | ||
This project is in alpha status. The implementation of the Fantasy Land spec should be *mostly* | ||
stable. Any methods outside of the Fantasy Land spec are subject to change. The types also have | ||
This project is in alpha status. The implementation of the Fantasy Land spec should be *mostly* | ||
stable. Any methods outside of the Fantasy Land spec are subject to change. The types also have | ||
not undergone thorough testing/use yet. | ||
@@ -18,11 +18,11 @@ | ||
Name | Setoid | Semigroup | Functor | Applicative | Monad | Comonad | | ||
---------- | :-----: | :-------: | :-----: | :---------: | :---: | :------: | | ||
Either | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | ||
Future | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | ||
Identity | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | ||
IO | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | ||
Maybe | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | ||
Reader | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | ||
Tuple | **✔︎** | **✔︎** | **✔︎** | **✔︎** | | | | ||
Name | Setoid | Semigroup | Functor | Applicative | Monad | Comonad | Foldable | | ||
---------- | :-----: | :-------: | :-----: | :---------: | :---: | :------: | :-------: | | ||
Either | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | | ||
Future | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | | ||
Identity | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | | ||
IO | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | | ||
Maybe | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | **✔︎** | | ||
Reader | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | | | ||
Tuple | **✔︎** | **✔︎** | **✔︎** | | | | | | ||
@@ -29,0 +29,0 @@ |
@@ -8,5 +8,13 @@ var R = require('ramda'); | ||
} | ||
this.fork = f; | ||
this._fork = f; | ||
} | ||
Future.prototype.fork = function(reject, resolve) { | ||
try { | ||
this._fork(reject, resolve); | ||
} catch(e) { | ||
reject(e); | ||
} | ||
}; | ||
// functor | ||
@@ -57,2 +65,3 @@ Future.prototype.map = function(f) { | ||
// chain must return a value of the same Chain | ||
//:: Future a, b => (b -> Future c) -> Future c | ||
Future.prototype.chain = function(f) { // Sorella's: | ||
@@ -65,2 +74,13 @@ return new Future(function(reject, resolve) { | ||
// chainReject | ||
// Like chain but operates on the reject instead of the resolve case. | ||
//:: Future a, b => (a -> Future c) -> Future c | ||
Future.prototype.chainReject = function(f) { | ||
return new Future(function(reject, resolve) { | ||
return this.fork(function(a) { return f(a).fork(reject, resolve); }, | ||
function(b) { return resolve(b); | ||
}); | ||
}.bind(this)); | ||
}; | ||
// monad | ||
@@ -88,5 +108,43 @@ // A value that implements the Monad specification must also implement the Applicative and Chain specifications. | ||
Future.prototype.toString = function() { | ||
return 'Future(' + R.toString(this.fork) + ')'; | ||
return 'Future(' + R.toString(this._fork) + ')'; | ||
}; | ||
Future.memoize = function(f) { | ||
var status = 'IDLE'; | ||
var listeners = []; | ||
var cachedValue; | ||
var handleCompletion = R.curry(function(newStatus, cb, val) { | ||
status = newStatus; | ||
cachedValue = val; | ||
cb(val); | ||
R.forEach(function(listener) { | ||
listener[status](cachedValue); | ||
}, listeners); | ||
}); | ||
function addListeners(reject, resolve) { | ||
listeners.push({ REJECTED: reject, RESOLVED: resolve } ); | ||
} | ||
function doResolve(reject, resolve) { | ||
status = 'PENDING'; | ||
return f.fork( | ||
handleCompletion('REJECTED', reject), | ||
handleCompletion('RESOLVED', resolve) | ||
); | ||
} | ||
return new Future(function(reject, resolve) { | ||
switch(status) { | ||
case 'IDLE': doResolve(reject, resolve); break; | ||
case 'PENDING': addListeners(reject, resolve); break; | ||
case 'REJECTED': reject(cachedValue); break; | ||
case 'RESOLVED': resolve(cachedValue); break; | ||
} | ||
}); | ||
}; | ||
module.exports = Future; |
@@ -18,3 +18,4 @@ var R = require('ramda'); | ||
return new IO(function() { | ||
return f(io.fn()).fn(); | ||
var next = f(io.fn.apply(io, arguments)); | ||
return next.fn.apply(next, arguments); | ||
}); | ||
@@ -50,11 +51,4 @@ }; | ||
// this is really only to accommodate testing .... | ||
IO.prototype.equals = function(that) { | ||
return this === that || | ||
this.fn === that.fn || | ||
R.equals(IO.runIO(this), IO.runIO(that)); | ||
}; | ||
IO.prototype.toString = function() { | ||
return 'IO(' + R.toString(this.fn) + ')'; | ||
}; |
var R = require('ramda'); | ||
module.exports = R.curryN(3, function liftA2(f, a1, a2) { | ||
module.exports = R.curryN(3, function lift2(f, a1, a2) { | ||
return a1.map(f).ap(a2); | ||
}); |
var R = require('ramda'); | ||
module.exports = R.curryN(4, function liftA2(f, a1, a2, a3) { | ||
module.exports = R.curryN(4, function lift3(f, a1, a2, a3) { | ||
return a1.map(f).ap(a2).ap(a3); | ||
}); |
@@ -39,2 +39,8 @@ var R = require('ramda'); | ||
Maybe.maybe = R.curry(function(nothingVal, justFn, m) { | ||
return m.reduce(function(_, x) { | ||
return justFn(x); | ||
}, nothingVal); | ||
}); | ||
// functor | ||
@@ -101,2 +107,10 @@ _Just.prototype.map = function(f) { | ||
_Just.prototype.reduce = function(f, x) { | ||
return f(x, this.value); | ||
}; | ||
_Nothing.prototype.reduce = function(f, x) { | ||
return x; | ||
}; | ||
_Just.prototype.toString = function() { | ||
@@ -103,0 +117,0 @@ return 'Maybe.Just(' + R.toString(this.value) + ')'; |
@@ -41,12 +41,4 @@ var R = require('ramda'); | ||
Reader.ask = Reader(function(a) { | ||
return a; | ||
}); | ||
Reader.ask = Reader(R.always); | ||
Reader.prototype.equals = function(that) { | ||
return this === that || | ||
this.run === that.run || | ||
R.equals(Reader.run(this), Reader.run(that)); | ||
}; | ||
Reader.prototype.toString = function() { | ||
@@ -56,2 +48,56 @@ return 'Reader(' + R.toString(this.run) + ')'; | ||
Reader.T = function(M) { | ||
var ReaderT = function ReaderT(run) { | ||
if (!(this instanceof ReaderT)) { | ||
return new ReaderT(run); | ||
} | ||
this.run = run; | ||
}; | ||
ReaderT.lift = R.compose(ReaderT, R.always); | ||
ReaderT.ask = ReaderT(M.of); | ||
ReaderT.prototype.of = ReaderT.of = function(a) { | ||
return ReaderT(function() { | ||
return M.of(a); | ||
}); | ||
}; | ||
ReaderT.prototype.chain = function(f) { | ||
var readerT = this; | ||
return ReaderT(function(e) { | ||
var m = readerT.run(e); | ||
return m.chain(function(a) { | ||
return f(a).run(e); | ||
}); | ||
}); | ||
}; | ||
ReaderT.prototype.map = function(f) { | ||
return this.chain(function(a) { | ||
return ReaderT.of(f(a)); | ||
}); | ||
}; | ||
ReaderT.prototype.ap = function(a) { | ||
var readerT = this; | ||
return ReaderT(function(e) { | ||
return readerT.run(e).ap(a.run(e)); | ||
}); | ||
}; | ||
ReaderT.prototype.equals = function(that) { | ||
return this === that || | ||
this.run === that.run || | ||
R.equals(this.run().get(), that.run().get()); | ||
}; | ||
ReaderT.prototype.toString = function() { | ||
return 'ReaderT[' + M.name + '](' + R.toString(this.run) + ')'; | ||
}; | ||
return ReaderT; | ||
}; | ||
module.exports = Reader; |
@@ -31,6 +31,2 @@ var R = require('ramda'); | ||
Tuple.of = function(x) { | ||
return Tuple(x, x); | ||
}; | ||
Tuple.fst = function(x) { | ||
@@ -44,6 +40,2 @@ return x[0]; | ||
_Tuple.prototype.of = function(x) { | ||
return Tuple(this[0], x); | ||
}; | ||
// semigroup | ||
@@ -50,0 +42,0 @@ _Tuple.prototype.concat = function(x) { |
var assert = require('assert'); | ||
var types = require('./types'); | ||
var equalsInvoker = require('./utils').equalsInvoker; | ||
var types = require('./types')(equalsInvoker); | ||
@@ -4,0 +5,0 @@ var Either = require('..').Either; |
var R = require('ramda'); | ||
var assert = require('assert'); | ||
var types = require('./types'); | ||
var equalsInvoker = require('./utils').equalsInvoker; | ||
var types = require('./types')(equalsInvoker); | ||
var Future = require('../src/Future'); | ||
@@ -89,2 +90,10 @@ | ||
describe('chainReject', function() { | ||
it('.chainReject should work like chain but off reject case', function() { | ||
var f1 = Future.reject(2); | ||
var f2 = function(val){ return Future.of(val + 3);}; | ||
assert.equal(true, Future.of(5).equals(f1.chainReject(f2))); | ||
}); | ||
}); | ||
describe('#ap', function() { | ||
@@ -197,3 +206,165 @@ /*jshint browser:true */ | ||
describe('#fork', function() { | ||
var result; | ||
var futureOne = Future.of(1); | ||
var throwError = function() { | ||
throw new Error('Some error message'); | ||
}; | ||
var setErrorResult = function(e) { | ||
result = e.message; | ||
}; | ||
beforeEach(function() { | ||
result = null; | ||
}); | ||
it('creates a rejected future if the resolve function throws an error', function() { | ||
futureOne.fork(setErrorResult, throwError); | ||
assert.equal('Some error message', result); | ||
}); | ||
it('rejects the future if an error is thrown in a map function', function() { | ||
futureOne.map(throwError).fork(setErrorResult); | ||
assert.equal('Some error message', result); | ||
}); | ||
it('rejects the future if an error is thrown in a chain function', function() { | ||
futureOne.chain(throwError).fork(setErrorResult); | ||
assert.equal('Some error message', result); | ||
}); | ||
it('rejects the future if an error is thrown in a ap function', function() { | ||
Future.of(throwError).ap(futureOne).fork(setErrorResult); | ||
assert.equal('Some error message', result); | ||
}); | ||
}); | ||
describe('#memoize', function() { | ||
var memoized; | ||
var throwIfCalledTwice; | ||
beforeEach(function() { | ||
throwIfCalledTwice = (function() { | ||
var count = 0; | ||
return function(val) { | ||
if (++count > 1) { | ||
throw new Error('Was called twice'); | ||
} | ||
return val; | ||
}; | ||
}()); | ||
}); | ||
describe('resolve cases', function() { | ||
beforeEach(function() { | ||
memoized = Future.memoize(Future.of(1).map(throwIfCalledTwice)); | ||
}); | ||
it('can be forked with a resolved value', function(done) { | ||
memoized.fork(done, function(v) { | ||
assert.equal(1, v); | ||
done(); | ||
}); | ||
}); | ||
it('passes on the same value to the memoized future', function(done) { | ||
memoized.fork(done, function() { | ||
memoized.fork(done, function(v) { | ||
assert.equal(1, v); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('reject cases', function() { | ||
var throwError = function() { | ||
throw new Error('SomeError'); | ||
}; | ||
beforeEach(function() { | ||
memoized = Future.memoize(Future.of(1).map(throwIfCalledTwice).map(throwError)); | ||
}); | ||
it('can be forked with a rejected value', function() { | ||
var result; | ||
memoized.fork(function(err) { | ||
result = err.message; | ||
}); | ||
assert.equal('SomeError', result); | ||
}); | ||
it('does not call the underlying fork twice', function() { | ||
var result; | ||
memoized.fork(function() { | ||
memoized.fork(function(err) { | ||
result = err.message; | ||
}); | ||
}); | ||
assert.equal('SomeError', result); | ||
}); | ||
}); | ||
describe('pending cases', function() { | ||
it('calls all fork resolve functions when the memoized future is resolved', function(done) { | ||
var delayed = new Future(function(reject, resolve) { | ||
setTimeout(resolve, 5, 'resolvedValue'); | ||
}); | ||
var memoized = Future.memoize(delayed.map(throwIfCalledTwice)); | ||
var result1; | ||
var result2; | ||
function assertBoth() { | ||
if (result1 !== undefined && result2 !== undefined) { | ||
assert.equal('resolvedValue', result1); | ||
assert.equal('resolvedValue', result2); | ||
done(); | ||
} | ||
} | ||
memoized.fork(done, function(v) { | ||
result1 = v; | ||
assertBoth(); | ||
}); | ||
memoized.fork(done, function(v) { | ||
result2 = v; | ||
assertBoth(); | ||
}); | ||
}); | ||
it('calls all fork reject fnctions when the memoized future is rejected', function(done) { | ||
var delayed = new Future(function(reject) { | ||
setTimeout(reject, 5, 'rejectedValue'); | ||
}); | ||
var memoized = Future.memoize(delayed.bimap(throwIfCalledTwice, R.identity)); | ||
var result1; | ||
var result2; | ||
function assertBoth() { | ||
if (result1 !== undefined && result2 !== undefined) { | ||
assert.equal('rejectedValue', result1); | ||
assert.equal('rejectedValue', result2); | ||
done(); | ||
} | ||
} | ||
memoized.fork(function(e) { | ||
result1 = e; | ||
assertBoth(); | ||
}); | ||
memoized.fork(function(e) { | ||
result2 = e; | ||
assertBoth(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
var assert = require('assert'); | ||
var types = require('./types'); | ||
var equalsInvoker = require('./utils').equalsInvoker; | ||
var types = require('./types')(equalsInvoker); | ||
@@ -4,0 +5,0 @@ var Identity = require('..').Identity; |
var assert = require('assert'); | ||
var types = require('./types'); | ||
var types = require('./types')(function(io1, io2) { | ||
return io1.runIO('x') === io2.runIO('x'); | ||
}); | ||
@@ -4,0 +6,0 @@ var IO = require('..').IO; |
var R = require('ramda'); | ||
var assert = require('assert'); | ||
var types = require('./types'); | ||
var equalsInvoker = require('./utils').equalsInvoker; | ||
var types = require('./types')(equalsInvoker); | ||
var jsv = require('jsverify'); | ||
@@ -83,2 +84,13 @@ | ||
it('is Foldable', function() { | ||
var fTest = types.foldable; | ||
jsv.assert(jsv.forall(m, fTest.iface)); | ||
jsv.assert(jsv.forall('nat -> nat -> nat', 'nat', 'nat', function(f, n1, n2) { | ||
return Maybe.Just(n1).reduce(R.uncurryN(2, f), n2) === f(n2)(n1); | ||
})); | ||
jsv.assert(jsv.forall('nat -> nat -> nat', 'nat', function(f, n) { | ||
return Maybe.Nothing().reduce(R.uncurryN(2, f), n) === n; | ||
})); | ||
}); | ||
}); | ||
@@ -135,2 +147,16 @@ | ||
describe('#maybe', function() { | ||
it('returns the result of applying the value of a Just to the second argument', function() { | ||
jsv.assert(jsv.forall('nat -> nat', 'nat', 'nat', function(f, n1, n2) { | ||
return R.equals(Maybe.maybe(n2, f, Maybe.Just(n1)), f(n1)); | ||
})); | ||
}); | ||
it('returns the first argument for a Nothing', function() { | ||
jsv.assert(jsv.forall('nat -> nat', 'nat', 'nat', function(f, n) { | ||
return R.equals(Maybe.maybe(n, f, Maybe.Nothing()), n); | ||
})); | ||
}); | ||
}); | ||
}); |
var assert = require('assert'); | ||
var types = require('./types'); | ||
var Reader = require('..').Reader; | ||
var readerTypes = types(function(r1, r2) { | ||
return r1.run('x') === r2.run('x'); | ||
}); | ||
var transformerTypes = types(function(r1, r2) { | ||
return r1.run('x').get() === r2.run('x').get(); | ||
}); | ||
var Identity = require('..').Identity; | ||
var Reader = require('../src/Reader'); | ||
var ReaderTIdentity = Reader.T(Identity); | ||
function add(a) { | ||
@@ -29,3 +40,3 @@ return function(b) { return a + b; }; | ||
it('is a Functor', function() { | ||
var fTest = types.functor; | ||
var fTest = readerTypes.functor; | ||
assert.ok(fTest.iface(r1)); | ||
@@ -37,3 +48,3 @@ assert.ok(fTest.id(r1)); | ||
it('is an Apply', function() { | ||
var aTest = types.apply; | ||
var aTest = readerTypes.apply; | ||
var a = Reader(function() { return add(1); }); | ||
@@ -48,3 +59,3 @@ var b = Reader(function() { return always(2); }); | ||
it('is an Applicative', function() { | ||
var aTest = types.applicative; | ||
var aTest = readerTypes.applicative; | ||
@@ -62,3 +73,3 @@ assert.equal(true, aTest.iface(r1)); | ||
it('is a Chain', function() { | ||
var cTest = types.chain; | ||
var cTest = readerTypes.chain; | ||
var c = Reader(function() { | ||
@@ -76,3 +87,3 @@ return Reader(function() { | ||
it('is a Monad', function() { | ||
var mTest = types.monad; | ||
var mTest = readerTypes.monad; | ||
assert.equal(true, mTest.iface(r1)); | ||
@@ -109,4 +120,80 @@ }); | ||
assert.equal(nameReader.run(Printer), '/** header */'); | ||
assert.equal(Reader.run(nameReader, Printer), '/** header */'); | ||
}); | ||
}); | ||
describe('Reader.T', function() { | ||
var r1 = ReaderTIdentity(function(x) { | ||
return Identity(x + '1 '); | ||
}); | ||
var r2 = ReaderTIdentity(function(x) { | ||
return Identity(x + '2 '); | ||
}); | ||
it('is a Functor', function() { | ||
var fTest = transformerTypes.functor; | ||
assert(fTest.iface(r1)); | ||
assert(fTest.id(r1)); | ||
assert(fTest.compose(r1, | ||
function(x) { return x + 'a'; }, | ||
function(x) { return x + 'b'; } | ||
)); | ||
}); | ||
it('is an Apply', function() { | ||
var aTest = transformerTypes.apply; | ||
var a = ReaderTIdentity(function() { return Identity(add(1)); }); | ||
var b = ReaderTIdentity(function() { return Identity(always(2)); }); | ||
var c = ReaderTIdentity(always(Identity(4))); | ||
assert(aTest.iface(r1)); | ||
assert(aTest.compose(a, b, c)); | ||
}); | ||
it('is an Applicative', function() { | ||
var aTest = transformerTypes.applicative; | ||
assert(aTest.iface(r1)); | ||
assert(aTest.id(ReaderTIdentity, r2)); | ||
assert(aTest.homomorphic(r1, add(3), 46)); | ||
assert(aTest.interchange( | ||
ReaderTIdentity(function() { return Identity(mult(20)); }), | ||
ReaderTIdentity(function() { return Identity(mult(0.5)); }), | ||
73 | ||
)); | ||
}); | ||
it('is a Chain', function() { | ||
var cTest = transformerTypes.chain; | ||
var c = ReaderTIdentity(function() { | ||
return Identity(ReaderTIdentity(function() { | ||
return Identity(ReaderTIdentity(function() { | ||
return Identity(3); | ||
})); | ||
})); | ||
}); | ||
assert(cTest.iface(r1)); | ||
assert(cTest.associative(c, identity, identity)); | ||
}); | ||
it('is a Monad', function() { | ||
var mTest = transformerTypes.monad; | ||
assert(mTest.iface(r1)); | ||
}); | ||
it('is a Transformer', function() { | ||
var mtTest = transformerTypes.transformer; | ||
assert(mtTest.iface(Reader.T)); | ||
assert(mtTest.id(Reader.T)); | ||
assert(mtTest.associative(Reader.T)); | ||
}); | ||
}); | ||
describe('Reader.T examples', function() { | ||
it('should provide its environment to a lifted monad', function() { | ||
var readerTimes10 = ReaderTIdentity.ask.chain(function(env) { | ||
return ReaderTIdentity.lift(Identity(env * 10)); | ||
}); | ||
assert.strictEqual(readerTimes10.run(3).get(), 30); | ||
}); | ||
}); |
var R = require('ramda'); | ||
var assert = require('assert'); | ||
var types = require('./types'); | ||
var equalsInvoker = require('./utils').equalsInvoker; | ||
var types = require('./types')(equalsInvoker); | ||
var jsv = require('jsverify'); | ||
@@ -87,14 +88,2 @@ | ||
}); | ||
it('is an Applicative', function() { | ||
var aTest = types.applicative; | ||
var app1 = Tuple('', 101); | ||
var app2 = Tuple('', -123); | ||
var appF = Tuple('', mult(3)); | ||
assert.equal(true, aTest.iface(app1)); | ||
assert.equal(true, aTest.id(app1, app2)); | ||
assert.equal(true, aTest.homomorphic(app1, add(3), 46)); | ||
assert.equal(true, aTest.interchange(app2, appF, 17)); | ||
}); | ||
}); | ||
@@ -110,14 +99,2 @@ | ||
}); | ||
it('should lift the value into the tuple as both positions', function() { | ||
var tpl = Tuple.of('pillow pets'); | ||
assert.equal('pillow pets', tpl[0]); | ||
assert.equal('pillow pets', tpl[1]); | ||
}); | ||
it('should maintain the current fst if it already has one', function() { | ||
var tpl = Tuple.of(100).of('buckaroonies'); | ||
assert.equal(100, tpl[0]); | ||
assert.equal('buckaroonies', tpl[1]); | ||
}); | ||
}); | ||
@@ -124,0 +101,0 @@ |
@@ -9,5 +9,9 @@ var interfaces = { | ||
monad: ['map', 'ap', 'chain', 'of'], | ||
extend: ['extend'] | ||
extend: ['extend'], | ||
foldable: ['reduce'], | ||
transformer: ['lift'] | ||
}; | ||
var Identity = require('..').Identity; | ||
function correctInterface(type) { | ||
@@ -23,68 +27,108 @@ return function(obj) { | ||
module.exports = { | ||
semigroup: { | ||
iface: correctInterface('semigroup'), | ||
associative: function(a, b, c) { | ||
return a.concat(b).concat(c).equals(a.concat(b.concat(c))); | ||
} | ||
}, | ||
module.exports = function(eq) { | ||
return { | ||
semigroup: { | ||
iface: correctInterface('semigroup'), | ||
associative: function (a, b, c) { | ||
return eq(a.concat(b).concat(c), a.concat(b.concat(c))); | ||
} | ||
}, | ||
functor: { | ||
iface: correctInterface('functor'), | ||
id: function(obj) { | ||
return obj.equals(obj.map(identity)); | ||
functor: { | ||
iface: correctInterface('functor'), | ||
id: function (obj) { | ||
return eq(obj, obj.map(identity)); | ||
}, | ||
compose: function (obj, f, g) { | ||
return eq( | ||
obj.map(function (x) { | ||
return f(g(x)); | ||
}), | ||
obj.map(g).map(f) | ||
); | ||
} | ||
}, | ||
compose: function(obj, f, g) { | ||
return obj.map(function(x) { return f(g(x)); }).equals( | ||
obj.map(g).map(f) | ||
); | ||
} | ||
}, | ||
apply: { | ||
iface: correctInterface('apply'), | ||
compose: function(a, u, v) { | ||
return a.ap(u.ap(v)).equals( | ||
a.map(function(f) { | ||
return function(g) { | ||
return function(x) { | ||
return f(g(x)); | ||
apply: { | ||
iface: correctInterface('apply'), | ||
compose: function (a, u, v) { | ||
return eq( | ||
a.ap(u.ap(v)), | ||
a.map(function (f) { | ||
return function (g) { | ||
return function (x) { | ||
return f(g(x)); | ||
}; | ||
}; | ||
}; | ||
}).ap(u).ap(v) | ||
); | ||
} | ||
}, | ||
}).ap(u).ap(v) | ||
); | ||
} | ||
}, | ||
applicative: { | ||
iface: correctInterface('applicative'), | ||
id: function(obj, obj2) { | ||
return obj.of(identity).ap(obj2).equals(obj2); | ||
applicative: { | ||
iface: correctInterface('applicative'), | ||
id: function (obj, obj2) { | ||
return eq(obj.of(identity).ap(obj2), obj2); | ||
}, | ||
homomorphic: function (obj, f, x) { | ||
return eq(obj.of(f).ap(obj.of(x)), obj.of(f(x))); | ||
}, | ||
interchange: function (obj1, obj2, x) { | ||
return eq( | ||
obj2.ap(obj1.of(x)), | ||
obj1.of(function (f) { | ||
return f(x); | ||
}).ap(obj2) | ||
); | ||
} | ||
}, | ||
homomorphic: function(obj, f, x) { | ||
return obj.of(f).ap(obj.of(x)).equals(obj.of(f(x))); | ||
chain: { | ||
iface: correctInterface('chain'), | ||
associative: function (obj, f, g) { | ||
return eq( | ||
obj.chain(f).chain(g), | ||
obj.chain(function (x) { | ||
return f(x).chain(g); | ||
}) | ||
); | ||
} | ||
}, | ||
interchange: function(obj1, obj2, x) { | ||
return obj2.ap(obj1.of(x)).equals( | ||
obj1.of(function(f) { return f(x); }).ap(obj2) | ||
); | ||
} | ||
}, | ||
chain: { | ||
iface: correctInterface('chain'), | ||
associative: function(obj, f, g) { | ||
return obj.chain(f).chain(g).equals( | ||
obj.chain(function(x) { return f(x).chain(g); }) | ||
); | ||
} | ||
}, | ||
monad: { | ||
iface: correctInterface('monad') | ||
}, | ||
monad: { | ||
iface: correctInterface('monad') | ||
}, | ||
extend: { | ||
iface: correctInterface('extend') | ||
}, | ||
extend: { | ||
iface: correctInterface('extend') | ||
} | ||
foldable: { | ||
iface: correctInterface('foldable') | ||
}, | ||
transformer: { | ||
iface: function (T) { | ||
return correctInterface('transformer')(T(Identity)) && | ||
correctInterface('monad')(T(Identity)(identity)); | ||
}, | ||
id: function (transformer) { | ||
var T = transformer(Identity); | ||
return eq(T.lift(Identity.of(1)), T.of(1)); | ||
}, | ||
associative: function (transformer) { | ||
var T = transformer(Identity); | ||
var m = Identity(1); | ||
var f = function (x) { | ||
return Identity(x * x); | ||
}; | ||
return eq( | ||
T.lift(m.chain(f)), | ||
T.lift(m).chain(function (x) { | ||
return T.lift(f(x)); | ||
}) | ||
); | ||
} | ||
} | ||
}; | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
58080
28
1734
0
+ Addedramda@0.17.1(transitive)
- Removedramda@0.15.1(transitive)
Updatedramda@>=0.15.0 <0.18.0