Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ramda-fantasy

Package Overview
Dependencies
Maintainers
3
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ramda-fantasy - npm Package Compare versions

Comparing version 0.6.1 to 0.7.0

.idea/.name

2

bower.json
{
"name": "ramda-fantasy",
"description": "Fantasy Land compatible types for easy integration with Ramda",
"version": "0.6.1",
"version": "0.7.0",
"authors": [

@@ -6,0 +6,0 @@ {

# Future
The `Future` type is used to represent some future, often asynchronous,
action that may potentially fail. It is similar to native the JS `Promise` type,
action that may potentially fail. It is similar to the native JS `Promise` type,
however the computation of a `Promise` is executed immediately, while the

@@ -6,0 +6,0 @@ execution of a `Future` instance is delayed until explicitly requested.

module.exports = {
Either: require('./src/Either'),
Future: require('./src/Future'),
Identity: require('./src/Identity'),
IO: require('./src/IO'),
lift2: require('./src/lift2'),
lift3: require('./src/lift3'),
Maybe: require('./src/Maybe'),
Tuple: require('./src/Tuple'),
Reader: require('./src/Reader')
Either: require('./src/Either'),
Future: require('./src/Future'),
Identity: require('./src/Identity'),
IO: require('./src/IO'),
lift2: require('./src/lift2'),
lift3: require('./src/lift3'),
Maybe: require('./src/Maybe'),
Reader: require('./src/Reader'),
State: require('./src/State'),
Tuple: require('./src/Tuple')
};

@@ -16,3 +16,3 @@ {

"description": "Fantasy Land compatible types for easy integration with Ramda",
"version": "0.6.1",
"version": "0.7.0",
"homepage": "https://www.github.com/ramda/ramda-fantasy",

@@ -41,2 +41,3 @@ "license": "MIT",

"mocha": "^2.1.0",
"promise": "7.1.1",
"uglify-js": "2.4.x",

@@ -43,0 +44,0 @@ "xyz": "0.5.x"

@@ -13,11 +13,11 @@ ramda-fantasy

| Name | [Setoid][3] | [Semigroup][4] | [Functor][5] | [Applicative][6] | [Monad][7] | [Foldable][8] |
| --------------- | :----------: | :------------: | :----------: | :--------------: | :--------: | :-----------: |
| [Either][9] | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | |
| [Future][10] | | | **✔︎** | **✔︎** | **✔︎** | |
| [Identity][11] | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | |
| [IO][12] | | | **✔︎** | **✔︎** | **✔︎** | |
| [Maybe][13] | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | **✔︎** |
| [Reader][14] | | | **✔︎** | **✔︎** | **✔︎** | |
| [Tuple][15] | **✔︎** | **✔︎** | **✔︎** | | | |
| Name | [Setoid][3] | [Semigroup][4] | [Functor][5] | [Applicative][6] | [Monad][7] | [Foldable][8] | [ChainRec][16] |
| --------------- | :----------: | :------------: | :----------: | :--------------: | :--------: | :-----------: | :------------: |
| [Either][9] | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | **✔︎** |
| [Future][10] | | | **✔︎** | **✔︎** | **✔︎** | | **✔︎** |
| [Identity][11] | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | | **✔︎** |
| [IO][12] | | | **✔︎** | **✔︎** | **✔︎** | | **✔︎** |
| [Maybe][13] | **✔︎** | | **✔︎** | **✔︎** | **✔︎** | **✔︎** | **✔︎** |
| [Reader][14] | | | **✔︎** | **✔︎** | **✔︎** | | |
| [Tuple][15] | **✔︎** | **✔︎** | **✔︎** | | | | |

@@ -45,1 +45,2 @@

[15]: docs/Tuple.md
[16]: https://github.com/fantasyland/fantasy-land#chainrec

@@ -1,2 +0,3 @@

var R = require('ramda');
var curry = require('ramda/src/curry');
var toString = require('ramda/src/toString');

@@ -32,3 +33,3 @@ var util = require('./internal/util');

Either.either = R.curry(function either(leftFn, rightFn, e) {
Either.either = curry(function either(leftFn, rightFn, e) {
if (e instanceof _Left) {

@@ -73,2 +74,15 @@ return leftFn(e.value);

//chainRec
Either.chainRec = Either.prototype.chainRec = function(f, i) {
var res, state = util.chainRecNext(i);
while (state.isNext) {
res = f(util.chainRecNext, util.chainRecDone, state.value);
if (Either.isLeft(res)) {
return res;
}
state = res.value;
}
return Either.Right(state.value);
};
_Right.prototype.bimap = function(_, f) {

@@ -83,3 +97,3 @@ return new _Right(f(this.value));

_Right.prototype.toString = function() {
return 'Either.Right(' + R.toString(this.value) + ')';
return 'Either.Right(' + toString(this.value) + ')';
};

@@ -110,3 +124,3 @@

_Left.prototype.toString = function() {
return 'Either.Left(' + R.toString(this.value) + ')';
return 'Either.Left(' + toString(this.value) + ')';
};

@@ -113,0 +127,0 @@

@@ -1,3 +0,8 @@

var R = require('ramda');
var once = require('ramda/src/once');
var forEach = require('ramda/src/forEach');
var toString = require('ramda/src/toString');
var curry = require('ramda/src/curry');
var util = require('./internal/util');
function jail(handler, f){

@@ -38,3 +43,3 @@ return function(a){

var applyFn, val;
var doReject = R.once(rej);
var doReject = once(rej);

@@ -83,2 +88,47 @@ var resolveIfDone = jail(doReject, function() {

// chainRec
//
// Heavily influenced by the Aff MonadRec instance
// https://github.com/slamdata/purescript-aff/blob/51106474122d0e5aec8e3d5da5bb66cfe8062f55/src/Control/Monad/Aff.js#L263-L322
Future.chainRec = Future.prototype.chainRec = function(f, a) {
return Future(function(reject, resolve) {
return function go(acc) {
// isSync could be in three possable states
// * null - unresolved status
// * true - synchronous future
// * false - asynchronous future
var isSync = null;
var state = util.chainRecNext(acc);
var onResolve = function(v) {
// If the `isSync` is still unresolved, we have observed a
// synchronous future. Otherwise, `isSync` will be `false`.
if (isSync === null) {
isSync = true;
// Store the result for further synchronous processing.
state = v;
} else {
// When we have observed an asynchronous future, we use normal
// recursion. This is safe because we will be on a new stack.
(v.isNext ? go : resolve)(v.value);
}
};
while (state.isNext) {
isSync = null;
f(util.chainRecNext, util.chainRecDone, state.value).fork(reject, onResolve);
// If the `isSync` has already resolved to `true` by our `onResolve`, then
// we have observed a synchronous future. Otherwise it will still be `null`.
if (isSync === true) {
continue;
} else {
// If the status has not resolved yet, then we have observed an
// asynchronous or failed future so update status and exit the loop.
isSync = false;
return;
}
}
resolve(state.value);
}(a);
});
};
// chainReject

@@ -117,3 +167,3 @@ // Like chain but operates on the reject instead of the resolve case.

Future.prototype.toString = function() {
return 'Future(' + R.toString(this._fork) + ')';
return 'Future(' + toString(this._fork) + ')';
};

@@ -126,7 +176,7 @@

var handleCompletion = R.curry(function(newStatus, cb, val) {
var handleCompletion = curry(function(newStatus, cb, val) {
status = newStatus;
cachedValue = val;
cb(val);
R.forEach(function(listener) {
forEach(function(listener) {
listener[status](cachedValue);

@@ -133,0 +183,0 @@ }, listeners);

@@ -1,2 +0,2 @@

var R = require('ramda');
var toString = require('ramda/src/toString');

@@ -71,2 +71,11 @@ var util = require('./internal/util');

// chainRec
Identity.chainRec = Identity.prototype.chainRec = function(f, i) {
var state = util.chainRecNext(i);
while (state.isNext) {
state = f(util.chainRecNext, util.chainRecDone, state.value).get();
}
return Identity(state.value);
};
/**

@@ -86,5 +95,5 @@ * Returns the value of `Identity[a]`

Identity.prototype.toString = function() {
return 'Identity(' + R.toString(this.value) + ')';
return 'Identity(' + toString(this.value) + ')';
};
module.exports = Identity;

@@ -1,2 +0,2 @@

var _equals = require('ramda').equals;
var _equals = require('ramda/src/equals');

@@ -39,4 +39,30 @@

returnThis: function() { return this; }
returnThis: function() { return this; },
chainRecNext: function(v) {
return { isNext: true, value: v };
},
chainRecDone: function(v) {
return { isNext: false, value: v };
},
deriveAp: function (Type) {
return function(fa) {
return this.chain(function (f) {
return fa.chain(function (a) {
return Type.of(f(a));
});
});
};
},
deriveMap: function (Type) {
return function (f) {
return this.chain(function (a) {
return Type.of(f(a));
});
};
}
};

@@ -1,7 +0,8 @@

var R = require('ramda');
var compose = require('ramda/src/compose');
var toString = require('ramda/src/toString');
var util = require('./internal/util');
module.exports = IO;
var compose = R.compose;
function IO(fn) {

@@ -25,2 +26,13 @@ if (!(this instanceof IO)) {

//chainRec
IO.chainRec = IO.prototype.chainRec = function(f, i) {
return new IO(function() {
var state = util.chainRecNext(i);
while (state.isNext) {
state = f(util.chainRecNext, util.chainRecDone, state.value).fn();
}
return state.value;
});
};
IO.prototype.map = function(f) {

@@ -54,3 +66,3 @@ var io = this;

IO.prototype.toString = function() {
return 'IO(' + R.toString(this.fn) + ')';
return 'IO(' + toString(this.fn) + ')';
};

@@ -1,5 +0,5 @@

var R = require('ramda');
var curryN = require('ramda/src/curryN');
module.exports = R.curryN(3, function lift2(f, a1, a2) {
module.exports = curryN(3, function lift2(f, a1, a2) {
return a1.map(f).ap(a2);
});

@@ -1,5 +0,5 @@

var R = require('ramda');
var curryN = require('ramda/src/curryN');
module.exports = R.curryN(4, function lift3(f, a1, a2, a3) {
module.exports = curryN(4, function lift3(f, a1, a2, a3) {
return a1.map(f).ap(a2).ap(a3);
});

@@ -1,2 +0,3 @@

var R = require('ramda');
var toString = require('ramda/src/toString');
var curry = require('ramda/src/curry');

@@ -47,3 +48,3 @@ var util = require('./internal/util.js');

Maybe.maybe = R.curry(function(nothingVal, justFn, m) {
Maybe.maybe = curry(function(nothingVal, justFn, m) {
return m.reduce(function(_, x) {

@@ -83,2 +84,16 @@ return justFn(x);

//chainRec
Maybe.chainRec = Maybe.prototype.chainRec = function(f, i) {
var res, state = util.chainRecNext(i);
while (state.isNext) {
res = f(util.chainRecNext, util.chainRecDone, state.value);
if (Maybe.isNothing(res)) {
return res;
}
state = res.value;
}
return Maybe.Just(state.value);
};
//

@@ -125,3 +140,3 @@ Just.prototype.datatype = Just;

Just.prototype.toString = function() {
return 'Maybe.Just(' + R.toString(this.value) + ')';
return 'Maybe.Just(' + toString(this.value) + ')';
};

@@ -128,0 +143,0 @@

@@ -1,2 +0,5 @@

var R = require('ramda');
var compose = require('ramda/src/compose');
var identity = require('ramda/src/identity');
var toString = require('ramda/src/toString');
var always = require('ramda/src/always');

@@ -43,6 +46,6 @@

Reader.ask = Reader(R.identity);
Reader.ask = Reader(identity);
Reader.prototype.toString = function() {
return 'Reader(' + R.toString(this.run) + ')';
return 'Reader(' + toString(this.run) + ')';
};

@@ -58,3 +61,3 @@

ReaderT.lift = R.compose(ReaderT, R.always);
ReaderT.lift = compose(ReaderT, always);

@@ -92,10 +95,4 @@ ReaderT.ask = ReaderT(M.of);

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[' + M.name + '](' + toString(this.run) + ')';
};

@@ -102,0 +99,0 @@

@@ -1,2 +0,3 @@

var R = require('ramda');
var toString = require('ramda/src/toString');
var equals = require('ramda/src/equals');

@@ -26,3 +27,3 @@

if (typeof x.concat != 'function') {
throw new TypeError(R.toString(x) + ' must be a semigroup to perform this operation');
throw new TypeError(toString(x) + ' must be a semigroup to perform this operation');
}

@@ -61,9 +62,9 @@ });

_Tuple.prototype.equals = function(that) {
return that instanceof _Tuple && R.equals(this[0], that[0]) && R.equals(this[1], that[1]);
return that instanceof _Tuple && equals(this[0], that[0]) && equals(this[1], that[1]);
};
_Tuple.prototype.toString = function() {
return 'Tuple(' + R.toString(this[0]) + ', ' + R.toString(this[1]) + ')';
return 'Tuple(' + toString(this[0]) + ', ' + toString(this[1]) + ')';
};
module.exports = Tuple;

@@ -52,2 +52,44 @@ var R = require('ramda');

describe('ChainRec', function() {
it('is a ChainRec', function() {
var cTest = types.chainRec;
var predicate = function(a) {
return a.length > 5;
};
var done = Either.of;
var x = 1;
var initial = [x];
var next = function(a) {
return Either.of(a.concat([x]));
};
assert.equal(true, cTest.iface(Either.of(1)));
assert.equal(true, cTest.equivalence(Either, predicate, done, next, initial));
});
it('is stacksafe', function() {
assert.equal(true, Either.of('DONE').equals(Either.chainRec(function(next, done, n) {
if (n === 0) {
return Either.of(done('DONE'));
} else {
return Either.of(next(n - 1));
}
}, 100000)));
});
it('responds to failure immediately', function() {
assert.equal(true, Either.Left("ERROR").equals(Either.chainRec(function(/*next, done, n*/) {
return Either.Left("ERROR");
}, 100)));
});
it('responds to failure on next step', function() {
assert.equal(true, Either.Left("ERROR").equals(Either.chainRec(function(next, done, n) {
if (n === 0) {
return Either.Left("ERROR");
}
return Either.of(next(n - 1));
}, 100)));
});
});
it('is a Monad', function() {

@@ -54,0 +96,0 @@ jsv.assert(jsv.forall(eNatArb, types.monad.iface));

@@ -6,18 +6,33 @@ var R = require('ramda');

var Future = require('../src/Future');
var Promise = require('promise');
Future.prototype.equals = function(b) {
this.fork(function(e1) {
b.fork(function(e2) {
assert.equal(e1, e2);
}, function() {
assert.fail(null, e1, 'Futures not equal: f1 failed, f2 did not', '===');
var self = this;
return new Promise(function(resolve, reject) {
self.fork(function(e1) {
b.fork(function(e2) {
try {
assert.deepEqual(e1, e2);
} catch (e) { reject(e); }
resolve();
}, function() {
try{
assert.fail(null, e1, 'Futures not equal: f1 failed, f2 did not', '===');
} catch (e) { reject(e); }
reject();
});
}, function(v1) {
b.fork(function() {
try{
assert.fail(null, v1, 'Futures not equal: f1 succeeded, f2 did not', '===');
} catch (e) { reject(e); }
reject();
}, function(v2) {
try {
assert.deepEqual(v1, v2);
} catch (e) { reject(e); }
resolve();
});
});
}, function(v1) {
b.fork(function() {
assert.fail(null, v1, 'Futures not equal: f1 succeeded, f2 did not', '===');
}, function(v2) {
assert.equal(v1, v2);
});
});
return true;
};

@@ -27,6 +42,22 @@

it('should equal another future', function() {
var f1 = Future.of(2);
var f2 = Future.of(2);
assert.equal(true, f1.equals(f2));
describe('Equal', function() {
it('should equal another future', function() {
var f1 = Future.of(2);
var f2 = Future.of(2);
return f1.equals(f2);
});
it('should equal another future (async)', function() {
var f1 = Future.of(2);
var f2 = Future(function(rej, res) {
setTimeout(res, 1, 2);
});
return f1.equals(f2);
});
it('should equal another future (non-primitive value)', function() {
var f1 = Future.of([2,2]);
var f2 = Future.of([2,2]);
return f1.equals(f2);
});
});

@@ -38,4 +69,6 @@

assert.equal(true, fTest.iface(f));
assert.equal(true, fTest.id(f));
assert.equal(true, fTest.compose(f, R.multiply(2), R.add(3)));
return Promise.all([
fTest.id(f),
fTest.compose(f, R.multiply(2), R.add(3))
]);
});

@@ -49,3 +82,3 @@

assert.equal(true, aTest.iface(appA));
assert.equal(true, aTest.compose(appA, appU, appV));
return aTest.compose(appA, appU, appV);
});

@@ -60,5 +93,7 @@

assert.equal(true, aTest.iface(app1));
assert.equal(true, aTest.id(app1, app2));
assert.equal(true, aTest.homomorphic(app1, R.add(3), 46));
assert.equal(true, aTest.interchange(app1, appF, 17));
return Promise.all([
aTest.id(app1, app2),
aTest.homomorphic(app1, R.add(3), 46),
aTest.interchange(app1, appF, 17),
]);
});

@@ -73,5 +108,49 @@

assert.equal(true, cTest.iface(f));
assert.equal(true, cTest.associative(f, f1, f2));
return cTest.associative(f, f1, f2);
});
describe('ChainRec', function() {
it('is a ChainRec', function() {
var cTest = types.chainRec;
var predicate = function(a) {
return a.length > 5;
};
var done = Future.of;
var x = 1;
var initial = [x];
var next = function(a) {
return Future.of(a.concat([x]));
};
assert.equal(true, cTest.iface(Future.of(1)));
return cTest.equivalence(Future, predicate, done, next, initial);
});
it('works when mixing sync and async Futures', function() {
return Future.of('DONE').equals(Future.chainRec(function(next, done, n) {
if (n === 0) {
return Future.of(done('DONE'));
} else if (n > 100 || n === 1) {
return Future.of(next(n - 1));
} else {
return new Future(function(rej, res) { setTimeout(res, 0, next(n - 1)); });
}
}, 100000));
});
it('responds to failure immediately', function() {
return Future.reject('ERROR').equals(Future.chainRec(function(/*next, done, n*/) {
return Future.reject('ERROR');
}, 100));
});
it('responds to failure on next step', function() {
return Future.reject('ERROR').equals(Future.chainRec(function(next, done, n) {
if (n === 0) {
return Future.reject('ERROR');
}
return Future.of(next(n - 1));
}, 100));
});
});
it('is a Monad', function() {

@@ -85,3 +164,3 @@ var mTest = types.monad;

var result = Future.of(1).map(R.inc);
assert.equal(true, Future.of(2).equals(result));
return Future.of(2).equals(result);
});

@@ -94,3 +173,3 @@

var result = Future.of(1).chain(incInTheFuture);
assert.equal(true, Future.of(2).equals(result));
return Future.of(2).equals(result);
});

@@ -102,3 +181,3 @@

var f2 = function(val){ return Future.of(val + 3);};
assert.equal(true, Future.of(5).equals(f1.chainReject(f2)));
return Future.of(5).equals(f1.chainReject(f2));
});

@@ -133,3 +212,3 @@ });

var result = f1.ap(Future.of(2));
assert.equal(true, Future.of(3).equals(result));
return Future.of(3).equals(result);
});

@@ -409,2 +488,1 @@

});

@@ -60,2 +60,29 @@ var assert = require('assert');

describe('ChainRec', function() {
it('is a ChainRec', function() {
var cTest = types.chainRec;
var predicate = function(a) {
return a.length > 5;
};
var done = Identity.of;
var x = 1;
var initial = [x];
var next = function(a) {
return Identity.of(a.concat([x]));
};
assert.equal(true, cTest.iface(Identity.of(1)));
assert.equal(true, cTest.equivalence(Identity, predicate, done, next, initial));
});
it('is stacksafe', function() {
assert.equal(true, Identity.of('DONE').equals(Identity.chainRec(function(next, done, n) {
if (n === 0) {
return Identity.of(done('DONE'));
} else {
return Identity.of(next(n - 1));
}
}, 100000)));
});
});
it('is a Monad', function() {

@@ -62,0 +89,0 @@ var mTest = types.monad;

var assert = require('assert');
var equals = require('ramda/src/equals');
var types = require('./types')(function(io1, io2) {
return io1.runIO('x') === io2.runIO('x');
return io1.equals(io2);
});

@@ -8,2 +9,6 @@

IO.prototype.equals = function(b) {
return equals(this.runIO('x'), b.runIO('x'));
};
function add(a) {

@@ -89,2 +94,29 @@ return function(b) { return a + b; };

describe('ChainRec', function() {
it('is a ChainRec', function() {
var cTest = types.chainRec;
var predicate = function(a) {
return a.length > 5;
};
var done = IO.of;
var x = 1;
var initial = [x];
var next = function(a) {
return IO.of(a.concat([x]));
};
assert.equal(true, cTest.iface(IO.of(1)));
assert.equal(true, cTest.equivalence(IO, predicate, done, next, initial));
});
it('is stacksafe', function() {
assert.equal(true, IO.of('DONE').equals(IO.chainRec(function(next, done, n) {
if (n === 0) {
return IO.of(done('DONE'));
} else {
return IO.of(next(n - 1));
}
}, 100000)));
});
});
it('is a Monad', function() {

@@ -91,0 +123,0 @@ var mTest = types.monad;

@@ -78,2 +78,46 @@ var R = require('ramda');

describe('ChainRec', function() {
it('is a ChainRec', function() {
var cTest = types.chainRec;
var predicate = function(a) {
return a.length > 5;
};
var done = Maybe.of;
var x = 1;
var initial = [x];
var next = function(a) {
return Maybe.of(a.concat([x]));
};
assert.equal(true, cTest.iface(Maybe.of(1)));
assert.equal(true, cTest.equivalence(Maybe, predicate, done, next, initial));
});
it('is stacksafe', function() {
var a = Maybe.chainRec(function(next, done, n) {
if (n === 0) {
return Maybe.of(done('DONE'));
} else {
return Maybe.of(next(n - 1));
}
}, 100000);
console.log('a',a);
assert.equal(true, Maybe.of('DONE').equals(a));
});
it('responds to failure immediately', function() {
assert.equal(true, Maybe.Nothing().equals(Maybe.chainRec(function(/*next, done, n*/) {
return Maybe.Nothing();
}, 100)));
});
it('responds to failure on next step', function() {
return Maybe.Nothing().equals(Maybe.chainRec(function(next, done, n) {
if (n === 0) {
return Maybe.Nothing();
}
return Maybe.of(next(n - 1));
}, 100));
});
});
it('is a Monad', function() {

@@ -80,0 +124,0 @@ var mTest = types.monad;

@@ -8,2 +8,3 @@ var interfaces = {

chain: ['map', 'ap', 'chain'],
chainRec: ['map', 'ap', 'chain', 'chainRec'],
monad: ['map', 'ap', 'chain', 'of'],

@@ -97,2 +98,15 @@ extend: ['extend'],

},
chainRec: {
iface: correctInterface('chainRec'),
equivalence: function (T, p, d, n, x) {
return eq(
T.chainRec(function(next, done, v) {
return p(v) ? d(v).map(done) : n(v).map(next);
}, x),
(function step(v) {
return p(v) ? d(v) : n(v).chain(step);
}(x))
);
}
},

@@ -99,0 +113,0 @@ monad: {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc