Comparing version 4.3.5 to 5.0.0
489
es5.js
@@ -19,16 +19,10 @@ 'use strict'; | ||
if (module && typeof module.exports !== 'undefined') { | ||
module.exports = f(require('inspect-f'), require('sanctuary-type-classes')); | ||
module.exports = f(require('concurrify'), require('inspect-f'), require('sanctuary-type-classes'), require('sanctuary-type-identifiers')); | ||
} else { | ||
global.Fluture = f(global.inspectf, global.sanctuaryTypeClasses); | ||
global.Fluture = f(global.concurrify, global.inspectf, global.sanctuaryTypeClasses, global.sanctuaryTypeIdentifiers); | ||
} | ||
})( /*istanbul ignore next*/global || window || undefined, function (inspectf, Z) { | ||
})( /*istanbul ignore next*/global || window || undefined, function (concurrify, inspectf, Z, type) { | ||
'use strict'; | ||
/*istanbul ignore next*/ | ||
function deprecate(message) { | ||
(console.warn || console.log || noop).call(console, message); //eslint-disable-line | ||
} | ||
/////////////////// | ||
@@ -48,9 +42,4 @@ // Type checking // | ||
function isForkable(m) { | ||
deprecate('Future.isForkable() is deprecated'); | ||
return Boolean(m) && typeof m.fork === 'function' && m.fork.length >= 2; | ||
} | ||
function isFuture(m) { | ||
return m instanceof Future || Boolean(m) && m['@@type'] === TYPEOF_FUTURE; | ||
return m instanceof Future || type(m) === TYPEOF_FUTURE; | ||
} | ||
@@ -141,41 +130,4 @@ | ||
//Creates a dispatcher for a nullary method. | ||
function createNullaryDispatcher(method) { | ||
return function nullaryDispatch(m) { | ||
if (m && typeof m[method] === 'function') return m[method](); | ||
return error$invalidArgument('Future.' + method, 1, 'have a "' + method + '" method', m); | ||
}; | ||
} | ||
//Creates a dispatcher for a unary method. | ||
function createUnaryDispatcher(method) { | ||
return function unaryDispatch(a, m) { | ||
if (arguments.length === 1) return unaryPartial(unaryDispatch, a); | ||
if (m && typeof m[method] === 'function') return m[method](a); | ||
return error$invalidArgument('Future.' + method, 1, 'have a "' + method + '" method', m); | ||
}; | ||
} | ||
//Creates a dispatcher for a binary method. | ||
function createBinaryDispatcher(method) { | ||
return function binaryDispatch(a, b, m) { | ||
if (arguments.length === 1) return unaryPartial(binaryDispatch, a); | ||
if (arguments.length === 2) return binaryPartial(binaryDispatch, a, b); | ||
if (m && typeof m[method] === 'function') return m[method](a, b); | ||
return error$invalidArgument('Future.' + method, 2, 'have a "' + method + '" method', m); | ||
}; | ||
} | ||
//Creates a dispatcher for a binary method, but takes the object first rather than last. | ||
function createInvertedBinaryDispatcher(method) { | ||
return function invertedBinaryDispatch(m, a, b) { | ||
if (arguments.length === 1) return unaryPartial(invertedBinaryDispatch, m); | ||
if (arguments.length === 2) return binaryPartial(invertedBinaryDispatch, m, a); | ||
if (m && typeof m[method] === 'function') return m[method](a, b); | ||
return error$invalidArgument('Future.' + method, 0, 'have a "' + method + '" method', m); | ||
}; | ||
} | ||
//Creates an error about an invalid argument. | ||
function error$invalidArgument(it, at, expected, actual) { | ||
function invalidArgument(it, at, expected, actual) { | ||
throw new TypeError(it + ' expects its ' + ordinal[at] + ' argument to ' + expected + '\n Actual: ' + show(actual)); | ||
@@ -185,3 +137,3 @@ } | ||
//Creates an error message about a method being called with an invalid context. | ||
function error$invalidContext(it, actual) { | ||
function invalidContext(it, actual) { | ||
throw new TypeError(it + ' was invoked outside the context of a Future. You might want to use' + (' a dispatcher instead\n Called on: ' + show(actual))); | ||
@@ -195,3 +147,3 @@ } | ||
function Future(f) { | ||
if (!isFunction(f)) error$invalidArgument('Future', 0, 'be a function', f); | ||
if (!isFunction(f)) invalidArgument('Future', 0, 'be a function', f); | ||
return new SafeFuture(f); | ||
@@ -206,7 +158,7 @@ } | ||
if (arguments.length === 1) return unaryPartial(Future$chainRec, f); | ||
if (!isFunction(f)) error$invalidArgument('Future.chainRec', 0, 'be a function', f); | ||
if (!isFunction(f)) invalidArgument('Future.chainRec', 0, 'be a function', f); | ||
return new ChainRec(f, init); | ||
} | ||
Future.prototype['@@type'] = TYPEOF_FUTURE; | ||
Future['@@type'] = TYPEOF_FUTURE; | ||
Future.prototype._f = null; | ||
@@ -222,4 +174,4 @@ Future.prototype.extractLeft = function Future$extractLeft() { | ||
Future.prototype.ap = function Future$ap(m) { | ||
if (!isFuture(this)) error$invalidContext('Future#ap', this); | ||
if (!isFuture(m)) error$invalidArgument('Future#ap', 0, 'be a Future', m); | ||
if (!isFuture(this)) invalidContext('Future#ap', this); | ||
if (!isFuture(m)) invalidArgument('Future#ap', 0, 'be a Future', m); | ||
return new FutureAp(this, m); | ||
@@ -229,4 +181,4 @@ }; | ||
Future.prototype.map = function Future$map(f) { | ||
if (!isFuture(this)) error$invalidContext('Future#map', this); | ||
if (!isFunction(f)) error$invalidArgument('Future#map', 0, 'be a function', f); | ||
if (!isFuture(this)) invalidContext('Future#map', this); | ||
if (!isFunction(f)) invalidArgument('Future#map', 0, 'be a function', f); | ||
return new FutureMap(this, f); | ||
@@ -236,5 +188,5 @@ }; | ||
Future.prototype.bimap = function Future$bimap(f, g) { | ||
if (!isFuture(this)) error$invalidContext('Future#bimap', this); | ||
if (!isFunction(f)) error$invalidArgument('Future#bimap', 0, 'be a function', f); | ||
if (!isFunction(g)) error$invalidArgument('Future#bimap', 1, 'be a function', g); | ||
if (!isFuture(this)) invalidContext('Future#bimap', this); | ||
if (!isFunction(f)) invalidArgument('Future#bimap', 0, 'be a function', f); | ||
if (!isFunction(g)) invalidArgument('Future#bimap', 1, 'be a function', g); | ||
return new FutureBimap(this, f, g); | ||
@@ -244,4 +196,4 @@ }; | ||
Future.prototype.chain = function Future$chain(f) { | ||
if (!isFuture(this)) error$invalidContext('Future#chain', this); | ||
if (!isFunction(f)) error$invalidArgument('Future#chain', 0, 'be a function', f); | ||
if (!isFuture(this)) invalidContext('Future#chain', this); | ||
if (!isFunction(f)) invalidArgument('Future#chain', 0, 'be a function', f); | ||
return new FutureChain(this, f); | ||
@@ -251,4 +203,4 @@ }; | ||
Future.prototype.chainRej = function Future$chainRej(f) { | ||
if (!isFuture(this)) error$invalidContext('Future.chainRej', this); | ||
if (!isFunction(f)) error$invalidArgument('Future.chainRej', 0, 'a function', f); | ||
if (!isFuture(this)) invalidContext('Future.chainRej', this); | ||
if (!isFunction(f)) invalidArgument('Future.chainRej', 0, 'a function', f); | ||
return new FutureChainRej(this, f); | ||
@@ -258,4 +210,4 @@ }; | ||
Future.prototype.mapRej = function Future$mapRej(f) { | ||
if (!isFuture(this)) error$invalidContext('Future#mapRej', this); | ||
if (!isFunction(f)) error$invalidArgument('Future#mapRej', 0, 'be a function', f); | ||
if (!isFuture(this)) invalidContext('Future#mapRej', this); | ||
if (!isFunction(f)) invalidArgument('Future#mapRej', 0, 'be a function', f); | ||
return new FutureMapRej(this, f); | ||
@@ -265,3 +217,3 @@ }; | ||
Future.prototype.swap = function Future$swap() { | ||
if (!isFuture(this)) error$invalidContext('Future#swap', this); | ||
if (!isFuture(this)) invalidContext('Future#swap', this); | ||
return new FutureSwap(this); | ||
@@ -271,4 +223,4 @@ }; | ||
Future.prototype.race = function Future$race(m) { | ||
if (!isFuture(this)) error$invalidContext('Future#race', this); | ||
if (!isFuture(m)) error$invalidArgument('Future#race', 0, 'be a Future', m); | ||
if (!isFuture(this)) invalidContext('Future#race', this); | ||
if (!isFuture(m)) invalidArgument('Future#race', 0, 'be a Future', m); | ||
return new FutureRace(this, m); | ||
@@ -278,4 +230,4 @@ }; | ||
Future.prototype.and = function Future$and(m) { | ||
if (!isFuture(this)) error$invalidContext('Future#and', this); | ||
if (!isFuture(m)) error$invalidArgument('Future#and', 0, 'be a Future', m); | ||
if (!isFuture(this)) invalidContext('Future#and', this); | ||
if (!isFuture(m)) invalidArgument('Future#and', 0, 'be a Future', m); | ||
return new FutureAnd(this, m); | ||
@@ -285,4 +237,4 @@ }; | ||
Future.prototype.or = function Future$or(m) { | ||
if (!isFuture(this)) error$invalidContext('Future#or', this); | ||
if (!isFuture(m)) error$invalidArgument('Future#or', 0, 'be a Future', m); | ||
if (!isFuture(this)) invalidContext('Future#or', this); | ||
if (!isFuture(m)) invalidArgument('Future#or', 0, 'be a Future', m); | ||
return new FutureOr(this, m); | ||
@@ -292,4 +244,4 @@ }; | ||
Future.prototype.both = function Future$both(m) { | ||
if (!isFuture(this)) error$invalidContext('Future#both', this); | ||
if (!isFuture(m)) error$invalidArgument('Future#both', 0, 'be a Future', m); | ||
if (!isFuture(this)) invalidContext('Future#both', this); | ||
if (!isFuture(m)) invalidArgument('Future#both', 0, 'be a Future', m); | ||
return new FutureBoth(this, m); | ||
@@ -299,5 +251,5 @@ }; | ||
Future.prototype.fold = function Future$fold(f, g) { | ||
if (!isFuture(this)) error$invalidContext('Future#fold', this); | ||
if (!isFunction(f)) error$invalidArgument('Future#fold', 0, 'be a function', f); | ||
if (!isFunction(g)) error$invalidArgument('Future#fold', 1, 'be a function', g); | ||
if (!isFuture(this)) invalidContext('Future#fold', this); | ||
if (!isFunction(f)) invalidArgument('Future#fold', 0, 'be a function', f); | ||
if (!isFunction(g)) invalidArgument('Future#fold', 1, 'be a function', g); | ||
return new FutureFold(this, f, g); | ||
@@ -307,5 +259,5 @@ }; | ||
Future.prototype.hook = function Future$hook(dispose, consume) { | ||
if (!isFuture(this)) error$invalidContext('Future#hook', this); | ||
if (!isFunction(dispose)) error$invalidArgument('Future#hook', 0, 'be a function', dispose); | ||
if (!isFunction(consume)) error$invalidArgument('Future#hook', 1, 'be a function', consume); | ||
if (!isFuture(this)) invalidContext('Future#hook', this); | ||
if (!isFunction(dispose)) invalidArgument('Future#hook', 0, 'be a function', dispose); | ||
if (!isFunction(consume)) invalidArgument('Future#hook', 1, 'be a function', consume); | ||
return new FutureHook(this, dispose, consume); | ||
@@ -315,4 +267,4 @@ }; | ||
Future.prototype.finally = function Future$finally(m) { | ||
if (!isFuture(this)) error$invalidContext('Future#finally', this); | ||
if (!isFuture(m)) error$invalidArgument('Future#finally', 0, 'be a Future', m); | ||
if (!isFuture(this)) invalidContext('Future#finally', this); | ||
if (!isFuture(m)) invalidArgument('Future#finally', 0, 'be a Future', m); | ||
return new FutureFinally(this, m); | ||
@@ -322,3 +274,3 @@ }; | ||
Future.prototype.cache = function Future$cache() { | ||
if (!isFuture(this)) error$invalidContext('Future#cache', this); | ||
if (!isFuture(this)) invalidContext('Future#cache', this); | ||
return new CachedFuture(this); | ||
@@ -328,5 +280,5 @@ }; | ||
Future.prototype.fork = function Future$fork(rej, res) { | ||
if (!isFuture(this)) error$invalidContext('Future#fork', this); | ||
if (!isFunction(rej)) error$invalidArgument('Future#fork', 0, 'be a function', rej); | ||
if (!isFunction(res)) error$invalidArgument('Future#fork', 1, 'be a function', res); | ||
if (!isFuture(this)) invalidContext('Future#fork', this); | ||
if (!isFunction(rej)) invalidArgument('Future#fork', 0, 'be a function', rej); | ||
if (!isFunction(res)) invalidArgument('Future#fork', 1, 'be a function', res); | ||
return this._f(rej, res); | ||
@@ -336,4 +288,4 @@ }; | ||
Future.prototype.value = function Future$value(f) { | ||
if (!isFuture(this)) error$invalidContext('Future#value', this); | ||
if (!isFunction(f)) error$invalidArgument('Future#value', 0, 'be a function', f); | ||
if (!isFuture(this)) invalidContext('Future#value', this); | ||
if (!isFunction(f)) invalidArgument('Future#value', 0, 'be a function', f); | ||
return this._f(function Future$value$rej(e) { | ||
@@ -345,3 +297,3 @@ throw new Error('Future#value was called on a rejected Future\n Actual: Future.reject(' + show(e) + ')'); | ||
Future.prototype.promise = function Future$promise() { | ||
if (!isFuture(this)) error$invalidContext('Future#promise', this); | ||
if (!isFuture(this)) invalidContext('Future#promise', this); | ||
var _this = this; | ||
@@ -359,3 +311,3 @@ return new Promise(function Future$promise$do(resolve, reject) { | ||
function ap$mval(mval, mfunc) { | ||
if (!Z.Apply.test(mfunc)) error$invalidArgument('Future.ap', 1, 'be an Apply', mfunc); | ||
if (!Z.Apply.test(mfunc)) invalidArgument('Future.ap', 1, 'be an Apply', mfunc); | ||
return Z.ap(mval, mfunc); | ||
@@ -365,3 +317,3 @@ } | ||
Future.ap = function ap(mval, mfunc) { | ||
if (!Z.Apply.test(mval)) error$invalidArgument('Future.ap', 0, 'be an Apply', mval); | ||
if (!Z.Apply.test(mval)) invalidArgument('Future.ap', 0, 'be an Apply', mval); | ||
if (arguments.length === 1) return unaryPartial(ap$mval, mval); | ||
@@ -372,3 +324,3 @@ return ap$mval(mval, mfunc); | ||
function map$mapper(mapper, m) { | ||
if (!Z.Functor.test(m)) error$invalidArgument('Future.map', 1, 'be a Functor', m); | ||
if (!Z.Functor.test(m)) invalidArgument('Future.map', 1, 'be a Functor', m); | ||
return Z.map(mapper, m); | ||
@@ -378,3 +330,3 @@ } | ||
Future.map = function map(mapper, m) { | ||
if (!isFunction(mapper)) error$invalidArgument('Future.map', 0, 'be a Function', mapper); | ||
if (!isFunction(mapper)) invalidArgument('Future.map', 0, 'be a Function', mapper); | ||
if (arguments.length === 1) return unaryPartial(map$mapper, mapper); | ||
@@ -385,3 +337,3 @@ return map$mapper(mapper, m); | ||
function bimap$lmapper$rmapper(lmapper, rmapper, m) { | ||
if (!Z.Bifunctor.test(m)) error$invalidArgument('Future.bimap', 2, 'be a Bifunctor', m); | ||
if (!Z.Bifunctor.test(m)) invalidArgument('Future.bimap', 2, 'be a Bifunctor', m); | ||
return Z.bimap(lmapper, rmapper, m); | ||
@@ -391,3 +343,3 @@ } | ||
function bimap$lmapper(lmapper, rmapper, m) { | ||
if (!isFunction(rmapper)) error$invalidArgument('Future.bimap', 1, 'be a Function', rmapper); | ||
if (!isFunction(rmapper)) invalidArgument('Future.bimap', 1, 'be a Function', rmapper); | ||
if (arguments.length === 2) return binaryPartial(bimap$lmapper$rmapper, lmapper, rmapper); | ||
@@ -398,3 +350,3 @@ return bimap$lmapper$rmapper(lmapper, rmapper, m); | ||
Future.bimap = function bimap(lmapper, rmapper, m) { | ||
if (!isFunction(lmapper)) error$invalidArgument('Future.bimap', 0, 'be a Function', lmapper); | ||
if (!isFunction(lmapper)) invalidArgument('Future.bimap', 0, 'be a Function', lmapper); | ||
if (arguments.length === 1) return unaryPartial(bimap$lmapper, lmapper); | ||
@@ -406,3 +358,3 @@ if (arguments.length === 2) return bimap$lmapper(lmapper, rmapper); | ||
function chain$chainer(chainer, m) { | ||
if (!Z.Chain.test(m)) error$invalidArgument('Future.chain', 1, 'be a Chain', m); | ||
if (!Z.Chain.test(m)) invalidArgument('Future.chain', 1, 'be a Chain', m); | ||
return Z.chain(chainer, m); | ||
@@ -412,3 +364,3 @@ } | ||
Future.chain = function chain(chainer, m) { | ||
if (!isFunction(chainer)) error$invalidArgument('Future.chain', 0, 'be a Function', chainer); | ||
if (!isFunction(chainer)) invalidArgument('Future.chain', 0, 'be a Function', chainer); | ||
if (arguments.length === 1) return unaryPartial(chain$chainer, chainer); | ||
@@ -419,3 +371,3 @@ return chain$chainer(chainer, m); | ||
function and$left(left, right) { | ||
if (!isFuture(right)) error$invalidArgument('Future.and', 1, 'be a Future', right); | ||
if (!isFuture(right)) invalidArgument('Future.and', 1, 'be a Future', right); | ||
return new FutureAnd(left, right); | ||
@@ -425,3 +377,3 @@ } | ||
Future.and = function and(left, right) { | ||
if (!isFuture(left)) error$invalidArgument('Future.and', 0, 'be a Future', left); | ||
if (!isFuture(left)) invalidArgument('Future.and', 0, 'be a Future', left); | ||
if (arguments.length === 1) return unaryPartial(and$left, left); | ||
@@ -432,3 +384,3 @@ return and$left(left, right); | ||
function both$left(left, right) { | ||
if (!isFuture(right)) error$invalidArgument('Future.both', 1, 'be a Future', right); | ||
if (!isFuture(right)) invalidArgument('Future.both', 1, 'be a Future', right); | ||
return new FutureBoth(left, right); | ||
@@ -438,3 +390,3 @@ } | ||
Future.both = function both(left, right) { | ||
if (!isFuture(left)) error$invalidArgument('Future.both', 0, 'be a Future', left); | ||
if (!isFuture(left)) invalidArgument('Future.both', 0, 'be a Future', left); | ||
if (arguments.length === 1) return unaryPartial(both$left, left); | ||
@@ -453,3 +405,3 @@ return both$left(left, right); | ||
Future.after = function Future$after(n, x) { | ||
if (!isPositiveInteger(n)) error$invalidArgument('Future.after', 0, 'be a positive integer', n); | ||
if (!isPositiveInteger(n)) invalidArgument('Future.after', 0, 'be a positive integer', n); | ||
if (arguments.length === 1) return unaryPartial(Future$after$n, n); | ||
@@ -464,3 +416,3 @@ return Future$after$n(n, x); | ||
Future.rejectAfter = function rejectAfter(time, reason) { | ||
if (!isPositiveInteger(time)) error$invalidArgument('Future.rejectAfter', 0, 'be a positive integer', time); | ||
if (!isPositiveInteger(time)) invalidArgument('Future.rejectAfter', 0, 'be a positive integer', time); | ||
if (arguments.length === 1) return unaryPartial(rejectAfter$time, time); | ||
@@ -470,18 +422,4 @@ return rejectAfter$time(time, reason); | ||
Future.cast = function Future$cast(m) { | ||
deprecate('Future.cast() is deprecated. Please use Future((l, r) => {m.fork(l, r)})'); | ||
return new SafeFuture(function (l, r) { | ||
return void m.fork(l, r); | ||
}); | ||
}; | ||
Future.fromForkable = function Future$fromForkable(m) { | ||
deprecate('Future.fromForkable() is deprecated. Please use Future((l, r) => {m.fork(l, r)})'); | ||
return new SafeFuture(function (l, r) { | ||
return void m.fork(l, r); | ||
}); | ||
}; | ||
Future.try = function Future$try(f) { | ||
if (!isFunction(f)) error$invalidArgument('Future.try', 0, 'be a function', f); | ||
if (!isFunction(f)) invalidArgument('Future.try', 0, 'be a function', f); | ||
return new FutureTry(f); | ||
@@ -492,3 +430,3 @@ }; | ||
if (arguments.length === 1) return unaryPartial(Future$encase, f); | ||
if (!isFunction(f)) error$invalidArgument('Future.encase', 0, 'be a function', f); | ||
if (!isFunction(f)) invalidArgument('Future.encase', 0, 'be a function', f); | ||
return new FutureEncase(f, x); | ||
@@ -504,4 +442,4 @@ }; | ||
default: | ||
if (!isFunction(f)) error$invalidArgument('Future.encase2', 0, 'be a function', f); | ||
if (!isBinary(f)) error$invalidArgument('Future.encase2', 0, 'take two arguments', f); | ||
if (!isFunction(f)) invalidArgument('Future.encase2', 0, 'be a function', f); | ||
if (!isBinary(f)) invalidArgument('Future.encase2', 0, 'take two arguments', f); | ||
return new FutureEncase(f, x, y); | ||
@@ -520,4 +458,4 @@ } | ||
default: | ||
if (!isFunction(f)) error$invalidArgument('Future.encase3', 0, 'be a function', f); | ||
if (!isTernary(f)) error$invalidArgument('Future.encase3', 0, 'take three arguments', f); | ||
if (!isFunction(f)) invalidArgument('Future.encase3', 0, 'be a function', f); | ||
if (!isTernary(f)) invalidArgument('Future.encase3', 0, 'take three arguments', f); | ||
return new FutureEncase(f, x, y, z); | ||
@@ -529,3 +467,3 @@ } | ||
if (arguments.length === 1) return unaryPartial(Future$fromPromise, f); | ||
if (!isFunction(f)) error$invalidArgument('Future.fromPromise', 0, 'be a function', f); | ||
if (!isFunction(f)) invalidArgument('Future.fromPromise', 0, 'be a function', f); | ||
return new FutureFromPromise(f, x); | ||
@@ -541,4 +479,4 @@ }; | ||
default: | ||
if (!isFunction(f)) error$invalidArgument('Future.fromPromise2', 0, 'be a function', f); | ||
if (!isBinary(f)) error$invalidArgument('Future.fromPromise2', 0, 'take two arguments', f); | ||
if (!isFunction(f)) invalidArgument('Future.fromPromise2', 0, 'be a function', f); | ||
if (!isBinary(f)) invalidArgument('Future.fromPromise2', 0, 'take two arguments', f); | ||
return new FutureFromPromise(f, x, y); | ||
@@ -557,4 +495,4 @@ } | ||
default: | ||
if (!isFunction(f)) error$invalidArgument('Future.fromPromise3', 0, 'be a function', f); | ||
if (!isTernary(f)) error$invalidArgument('Future.fromPromise3', 0, 'take three arguments', f); | ||
if (!isFunction(f)) invalidArgument('Future.fromPromise3', 0, 'be a function', f); | ||
if (!isTernary(f)) invalidArgument('Future.fromPromise3', 0, 'take three arguments', f); | ||
return new FutureFromPromise(f, x, y, z); | ||
@@ -565,33 +503,167 @@ } | ||
Future.node = function Future$node(f) { | ||
if (!isFunction(f)) error$invalidArgument('Future.node', 0, 'be a function', f); | ||
if (!isFunction(f)) invalidArgument('Future.node', 0, 'be a function', f); | ||
return new FutureNode(f); | ||
}; | ||
Future.parallel = function Future$parallel(i, ms) { | ||
if (arguments.length === 1) return unaryPartial(Future$parallel, i); | ||
if (!isPositiveInteger(i)) error$invalidArgument('Future.parallel', 0, 'be a positive integer', i); | ||
if (!Array.isArray(ms)) error$invalidArgument('Future.parallel', 1, 'be an array', ms); | ||
function parallel$i(i, ms) { | ||
if (!Array.isArray(ms)) invalidArgument('Future.parallel', 1, 'be an array', ms); | ||
return new FutureParallel(i, ms); | ||
} | ||
Future.parallel = function parallel(i, ms) { | ||
if (!isPositiveInteger(i)) invalidArgument('Future.parallel', 0, 'be a positive integer', i); | ||
if (arguments.length === 1) return unaryPartial(parallel$i, i); | ||
return parallel$i(i, ms); | ||
}; | ||
Future.do = function Future$do(f) { | ||
if (!isFunction(f)) error$invalidArgument('Future.do', 0, 'be a function', f); | ||
if (!isFunction(f)) invalidArgument('Future.do', 0, 'be a function', f); | ||
return new FutureDo(f); | ||
}; | ||
Future.chainRej = createUnaryDispatcher('chainRej'); | ||
Future.mapRej = createUnaryDispatcher('mapRej'); | ||
Future.swap = createNullaryDispatcher('swap'); | ||
Future.fork = createBinaryDispatcher('fork'); | ||
Future.race = createUnaryDispatcher('race'); | ||
Future.or = createUnaryDispatcher('or'); | ||
Future.fold = createBinaryDispatcher('fold'); | ||
Future.hook = createInvertedBinaryDispatcher('hook'); | ||
Future.finally = createUnaryDispatcher('finally'); | ||
Future.value = createUnaryDispatcher('value'); | ||
Future.promise = createNullaryDispatcher('promise'); | ||
Future.cache = createNullaryDispatcher('cache'); | ||
Future.extractLeft = createNullaryDispatcher('extractLeft'); | ||
Future.extractRight = createNullaryDispatcher('extractRight'); | ||
function chainRej$chainer(chainer, m) { | ||
if (!isFuture(m)) invalidArgument('Future.chainRej', 1, 'be a Future', m); | ||
return new FutureChainRej(m, chainer); | ||
} | ||
Future.chainRej = function chainRej(chainer, m) { | ||
if (!isFunction(chainer)) invalidArgument('Future.chainRej', 0, 'be a Function', chainer); | ||
if (arguments.length === 1) return unaryPartial(chainRej$chainer, chainer); | ||
return chainRej$chainer(chainer, m); | ||
}; | ||
function mapRej$mapper(mapper, m) { | ||
if (!isFuture(m)) invalidArgument('Future.mapRej', 1, 'be a Future', m); | ||
return new FutureMapRej(m, mapper); | ||
} | ||
Future.mapRej = function mapRej(mapper, m) { | ||
if (!isFunction(mapper)) invalidArgument('Future.mapRej', 0, 'be a Function', mapper); | ||
if (arguments.length === 1) return unaryPartial(mapRej$mapper, mapper); | ||
return mapRej$mapper(mapper, m); | ||
}; | ||
function race$right(right, left) { | ||
if (!isFuture(left)) invalidArgument('Future.race', 1, 'be a Future', left); | ||
return new FutureRace(left, right); | ||
} | ||
Future.race = function race(right, left) { | ||
if (!isFuture(right)) invalidArgument('Future.race', 0, 'be a Future', right); | ||
if (arguments.length === 1) return unaryPartial(race$right, right); | ||
return race$right(right, left); | ||
}; | ||
function or$left(left, right) { | ||
if (!isFuture(right)) invalidArgument('Future.or', 1, 'be a Future', right); | ||
return new FutureOr(left, right); | ||
} | ||
Future.or = function or(left, right) { | ||
if (!isFuture(left)) invalidArgument('Future.or', 0, 'be a Future', left); | ||
if (arguments.length === 1) return unaryPartial(or$left, left); | ||
return or$left(left, right); | ||
}; | ||
function finally$right(right, left) { | ||
if (!isFuture(left)) invalidArgument('Future.finally', 1, 'be a Future', left); | ||
return new FutureFinally(left, right); | ||
} | ||
Future.finally = function finally$(right, left) { | ||
if (!isFuture(right)) invalidArgument('Future.finally', 0, 'be a Future', right); | ||
if (arguments.length === 1) return unaryPartial(finally$right, right); | ||
return finally$right(right, left); | ||
}; | ||
function value$cont(cont, m) { | ||
if (!isFuture(m)) invalidArgument('Future.value', 1, 'be a Future', m); | ||
return m.value(cont); | ||
} | ||
Future.value = function value(cont, m) { | ||
if (!isFunction(cont)) invalidArgument('Future.value', 0, 'be a Function', cont); | ||
if (arguments.length === 1) return unaryPartial(value$cont, cont); | ||
return value$cont(cont, m); | ||
}; | ||
Future.swap = function swap(m) { | ||
if (!isFuture(m)) invalidArgument('Future.swap', 0, 'be a Future', m); | ||
return new FutureSwap(m); | ||
}; | ||
Future.promise = function promise(m) { | ||
if (!isFuture(m)) invalidArgument('Future.promise', 0, 'be a Future', m); | ||
return m.promise(); | ||
}; | ||
Future.cache = function cache(m) { | ||
if (!isFuture(m)) invalidArgument('Future.cache', 0, 'be a Future', m); | ||
return new CachedFuture(m); | ||
}; | ||
Future.extractLeft = function extractLeft(m) { | ||
if (!isFuture(m)) invalidArgument('Future.extractLeft', 0, 'be a Future', m); | ||
return m.extractLeft(); | ||
}; | ||
Future.extractRight = function extractRight(m) { | ||
if (!isFuture(m)) invalidArgument('Future.extractRight', 0, 'be a Future', m); | ||
return m.extractRight(); | ||
}; | ||
function fork$f$g(f, g, m) { | ||
if (!isFuture(m)) invalidArgument('Future.fork', 2, 'be a Future', m); | ||
return m._f(f, g); | ||
} | ||
function fork$f(f, g, m) { | ||
if (!isFunction(g)) invalidArgument('Future.fork', 1, 'be a function', g); | ||
if (arguments.length === 2) return binaryPartial(fork$f$g, f, g); | ||
return fork$f$g(f, g, m); | ||
} | ||
Future.fork = function fork(f, g, m) { | ||
if (!isFunction(f)) invalidArgument('Future.fork', 0, 'be a function', f); | ||
if (arguments.length === 1) return unaryPartial(fork$f, f); | ||
if (arguments.length === 2) return fork$f(f, g); | ||
return fork$f(f, g, m); | ||
}; | ||
function fold$f$g(f, g, m) { | ||
if (!isFuture(m)) invalidArgument('Future.fold', 2, 'be a Future', m); | ||
return new FutureFold(m, f, g); | ||
} | ||
function fold$f(f, g, m) { | ||
if (!isFunction(g)) invalidArgument('Future.fold', 1, 'be a function', g); | ||
if (arguments.length === 2) return binaryPartial(fold$f$g, f, g); | ||
return fold$f$g(f, g, m); | ||
} | ||
Future.fold = function fold(f, g, m) { | ||
if (!isFunction(f)) invalidArgument('Future.fold', 0, 'be a function', f); | ||
if (arguments.length === 1) return unaryPartial(fold$f, f); | ||
if (arguments.length === 2) return fold$f(f, g); | ||
return fold$f(f, g, m); | ||
}; | ||
function hook$acquire$cleanup(acquire, cleanup, consume) { | ||
if (!isFunction(consume)) invalidArgument('Future.hook', 2, 'be a Future', consume); | ||
return new FutureHook(acquire, cleanup, consume); | ||
} | ||
function hook$acquire(acquire, cleanup, consume) { | ||
if (!isFunction(cleanup)) invalidArgument('Future.hook', 1, 'be a function', cleanup); | ||
if (arguments.length === 2) return binaryPartial(hook$acquire$cleanup, acquire, cleanup); | ||
return hook$acquire$cleanup(acquire, cleanup, consume); | ||
} | ||
Future.hook = function hook(acquire, cleanup, consume) { | ||
if (!isFuture(acquire)) invalidArgument('Future.hook', 0, 'be a Future', acquire); | ||
if (arguments.length === 1) return unaryPartial(hook$acquire, acquire); | ||
if (arguments.length === 2) return hook$acquire(acquire, cleanup); | ||
return hook$acquire(acquire, cleanup, consume); | ||
}; | ||
//Utilities. | ||
@@ -601,3 +673,2 @@ Future.util = { | ||
Done: Done, | ||
isForkable: isForkable, | ||
isFuture: isFuture, | ||
@@ -1007,3 +1078,3 @@ isThenable: isThenable, | ||
function check$do$g(g) { | ||
if (!isIterator(g)) error$invalidArgument('Future.do', 0, 'return an iterator, maybe you forgot the "*"', g); | ||
if (!isIterator(g)) invalidArgument('Future.do', 0, 'return an iterator, maybe you forgot the "*"', g); | ||
} | ||
@@ -1313,2 +1384,47 @@ | ||
function FutureParallelAp(mval, mfunc) { | ||
this._mval = mval; | ||
this._mfunc = mfunc; | ||
} | ||
FutureParallelAp.prototype = Object.create(Future.prototype); | ||
FutureParallelAp.prototype._f = function FutureParallelAp$fork(rej, res) { | ||
var func = void 0, | ||
val = void 0, | ||
okval = false, | ||
okfunc = false, | ||
rejected = false, | ||
c1 = void 0, | ||
c2 = void 0; | ||
function FutureParallelAp$rej(x) { | ||
if (!rejected) { | ||
rejected = true; | ||
rej(x); | ||
} | ||
} | ||
c1 = this._mval._f(FutureParallelAp$rej, function FutureParallelAp$fork$resVal(x) { | ||
c1 = noop; | ||
if (!okval) return void (okfunc = true, val = x); | ||
check$ap$f(func); | ||
res(func(x)); | ||
}); | ||
c2 = this._mfunc._f(FutureParallelAp$rej, function FutureParallelAp$fork$resFunc(f) { | ||
c2 = noop; | ||
if (!okfunc) return void (okval = true, func = f); | ||
check$ap$f(f); | ||
res(f(val)); | ||
}); | ||
return function FutureParallelAp$fork$cancel() { | ||
c1(); | ||
c2(); | ||
}; | ||
}; | ||
FutureParallelAp.prototype.toString = function FutureParallelAp$toString() { | ||
return 'new FutureParallelAp(' + this._mval.toString() + ', ' + this._mfunc.toString() + ')'; | ||
}; | ||
//---------- | ||
function FutureSwap(parent) { | ||
@@ -1545,5 +1661,5 @@ this._parent = parent; | ||
function FutureFinally(left, right) { | ||
this._left = left; | ||
this._right = right; | ||
function FutureFinally(computation, cleanup) { | ||
this._computation = computation; | ||
this._cleanup = cleanup; | ||
} | ||
@@ -1556,20 +1672,41 @@ | ||
var cancel = void 0; | ||
var r = _this._left._f(function FutureFinally$fork$rej(e) { | ||
cancel = _this._right._f(rej, function FutureFinally$fork$rej$res() { | ||
var cancelComputation = _this._computation._f(function FutureFinally$fork$rej(e) { | ||
cancel = _this._cleanup._f(rej, function FutureFinally$fork$rej$res() { | ||
rej(e); | ||
}); | ||
}, function FutureFinally$fork$res(x) { | ||
cancel = _this._right._f(rej, function FutureFinally$fork$res$res() { | ||
cancel = _this._cleanup._f(rej, function FutureFinally$fork$res$res() { | ||
res(x); | ||
}); | ||
}); | ||
return cancel || (cancel = r, function FutureFinally$fork$cancel() { | ||
if (cancel) return cancel; | ||
cancel = function FutureFinally$fork$cancelBoth() { | ||
cancelComputation(); | ||
_this._cleanup._f(noop, noop)(); | ||
}; | ||
return function FutureFinally$fork$cancel() { | ||
cancel(); | ||
}); | ||
}; | ||
}; | ||
FutureFinally.prototype.toString = function FutureFinally$toString() { | ||
return this._left.toString() + '.finally(' + this._right.toString() + ')'; | ||
return this._computation.toString() + '.finally(' + this._cleanup.toString() + ')'; | ||
}; | ||
//---------- | ||
function FutureNever() {} | ||
FutureNever.prototype = Object.create(Future.prototype); | ||
FutureNever.prototype._f = function FutureNever$fork() { | ||
return noop; | ||
}; | ||
FutureNever.prototype.toString = function FutureNever$toString() { | ||
return 'Future.never'; | ||
}; | ||
Future.never = new FutureNever(); | ||
Future.classes = { | ||
@@ -1595,2 +1732,3 @@ SafeFuture: SafeFuture, | ||
FutureAp: FutureAp, | ||
FutureParallelAp: FutureParallelAp, | ||
FutureSwap: FutureSwap, | ||
@@ -1603,6 +1741,25 @@ FutureRace: FutureRace, | ||
FutureHook: FutureHook, | ||
FutureFinally: FutureFinally | ||
FutureFinally: FutureFinally, | ||
FutureNever: FutureNever | ||
}; | ||
////////////// | ||
// Parallel // | ||
////////////// | ||
var ParallelFuture = concurrify(Future, Future.never, Future.race, function (mval, mfunc) { | ||
return new FutureParallelAp(mval, mfunc); | ||
}); | ||
function isParallel(x) { | ||
return x instanceof ParallelFuture || type(x) === ParallelFuture['@@type']; | ||
} | ||
Future.Par = ParallelFuture; | ||
Future.seq = function seq(par) { | ||
if (!isParallel(par)) invalidArgument('Future.seq', 0, 'to be a Par', par); | ||
return par.sequential; | ||
}; | ||
return Future; | ||
}); |
488
fluture.js
@@ -14,16 +14,21 @@ //// ____ _ _ | ||
if(module && typeof module.exports !== 'undefined'){ | ||
module.exports = f(require('inspect-f'), require('sanctuary-type-classes')); | ||
module.exports = f( | ||
require('concurrify'), | ||
require('inspect-f'), | ||
require('sanctuary-type-classes'), | ||
require('sanctuary-type-identifiers') | ||
); | ||
}else{ | ||
global.Fluture = f(global.inspectf, global.sanctuaryTypeClasses); | ||
global.Fluture = f( | ||
global.concurrify, | ||
global.inspectf, | ||
global.sanctuaryTypeClasses, | ||
global.sanctuaryTypeIdentifiers | ||
); | ||
} | ||
}(/*istanbul ignore next*/(global || window || this), function(inspectf, Z){ | ||
}(/*istanbul ignore next*/(global || window || this), function(concurrify, inspectf, Z, type){ | ||
'use strict'; | ||
/*istanbul ignore next*/ | ||
function deprecate(message){ | ||
(console.warn || console.log || noop).call(console, message); //eslint-disable-line | ||
} | ||
/////////////////// | ||
@@ -43,9 +48,4 @@ // Type checking // | ||
function isForkable(m){ | ||
deprecate('Future.isForkable() is deprecated'); | ||
return Boolean(m) && typeof m.fork === 'function' && m.fork.length >= 2; | ||
} | ||
function isFuture(m){ | ||
return m instanceof Future || Boolean(m) && m['@@type'] === TYPEOF_FUTURE; | ||
return m instanceof Future || type(m) === TYPEOF_FUTURE; | ||
} | ||
@@ -119,41 +119,4 @@ | ||
//Creates a dispatcher for a nullary method. | ||
function createNullaryDispatcher(method){ | ||
return function nullaryDispatch(m){ | ||
if(m && typeof m[method] === 'function') return m[method](); | ||
return error$invalidArgument(`Future.${method}`, 1, `have a "${method}" method`, m); | ||
}; | ||
} | ||
//Creates a dispatcher for a unary method. | ||
function createUnaryDispatcher(method){ | ||
return function unaryDispatch(a, m){ | ||
if(arguments.length === 1) return unaryPartial(unaryDispatch, a); | ||
if(m && typeof m[method] === 'function') return m[method](a); | ||
return error$invalidArgument(`Future.${method}`, 1, `have a "${method}" method`, m); | ||
}; | ||
} | ||
//Creates a dispatcher for a binary method. | ||
function createBinaryDispatcher(method){ | ||
return function binaryDispatch(a, b, m){ | ||
if(arguments.length === 1) return unaryPartial(binaryDispatch, a); | ||
if(arguments.length === 2) return binaryPartial(binaryDispatch, a, b); | ||
if(m && typeof m[method] === 'function') return m[method](a, b); | ||
return error$invalidArgument(`Future.${method}`, 2, `have a "${method}" method`, m); | ||
}; | ||
} | ||
//Creates a dispatcher for a binary method, but takes the object first rather than last. | ||
function createInvertedBinaryDispatcher(method){ | ||
return function invertedBinaryDispatch(m, a, b){ | ||
if(arguments.length === 1) return unaryPartial(invertedBinaryDispatch, m); | ||
if(arguments.length === 2) return binaryPartial(invertedBinaryDispatch, m, a); | ||
if(m && typeof m[method] === 'function') return m[method](a, b); | ||
return error$invalidArgument(`Future.${method}`, 0, `have a "${method}" method`, m); | ||
}; | ||
} | ||
//Creates an error about an invalid argument. | ||
function error$invalidArgument(it, at, expected, actual){ | ||
function invalidArgument(it, at, expected, actual){ | ||
throw new TypeError( | ||
@@ -165,3 +128,3 @@ `${it} expects its ${ordinal[at]} argument to ${expected}\n Actual: ${show(actual)}` | ||
//Creates an error message about a method being called with an invalid context. | ||
function error$invalidContext(it, actual){ | ||
function invalidContext(it, actual){ | ||
throw new TypeError( | ||
@@ -178,3 +141,3 @@ `${it} was invoked outside the context of a Future. You might want to use` | ||
function Future(f){ | ||
if(!isFunction(f)) error$invalidArgument('Future', 0, 'be a function', f); | ||
if(!isFunction(f)) invalidArgument('Future', 0, 'be a function', f); | ||
return new SafeFuture(f); | ||
@@ -189,7 +152,7 @@ } | ||
if(arguments.length === 1) return unaryPartial(Future$chainRec, f); | ||
if(!isFunction(f)) error$invalidArgument('Future.chainRec', 0, 'be a function', f); | ||
if(!isFunction(f)) invalidArgument('Future.chainRec', 0, 'be a function', f); | ||
return new ChainRec(f, init); | ||
} | ||
Future.prototype['@@type'] = TYPEOF_FUTURE; | ||
Future['@@type'] = TYPEOF_FUTURE; | ||
Future.prototype._f = null; | ||
@@ -201,4 +164,4 @@ Future.prototype.extractLeft = function Future$extractLeft(){ return [] }; | ||
Future.prototype.ap = function Future$ap(m){ | ||
if(!isFuture(this)) error$invalidContext('Future#ap', this); | ||
if(!isFuture(m)) error$invalidArgument('Future#ap', 0, 'be a Future', m); | ||
if(!isFuture(this)) invalidContext('Future#ap', this); | ||
if(!isFuture(m)) invalidArgument('Future#ap', 0, 'be a Future', m); | ||
return new FutureAp(this, m); | ||
@@ -208,4 +171,4 @@ }; | ||
Future.prototype.map = function Future$map(f){ | ||
if(!isFuture(this)) error$invalidContext('Future#map', this); | ||
if(!isFunction(f)) error$invalidArgument('Future#map', 0, 'be a function', f); | ||
if(!isFuture(this)) invalidContext('Future#map', this); | ||
if(!isFunction(f)) invalidArgument('Future#map', 0, 'be a function', f); | ||
return new FutureMap(this, f); | ||
@@ -215,5 +178,5 @@ }; | ||
Future.prototype.bimap = function Future$bimap(f, g){ | ||
if(!isFuture(this)) error$invalidContext('Future#bimap', this); | ||
if(!isFunction(f)) error$invalidArgument('Future#bimap', 0, 'be a function', f); | ||
if(!isFunction(g)) error$invalidArgument('Future#bimap', 1, 'be a function', g); | ||
if(!isFuture(this)) invalidContext('Future#bimap', this); | ||
if(!isFunction(f)) invalidArgument('Future#bimap', 0, 'be a function', f); | ||
if(!isFunction(g)) invalidArgument('Future#bimap', 1, 'be a function', g); | ||
return new FutureBimap(this, f, g); | ||
@@ -223,4 +186,4 @@ }; | ||
Future.prototype.chain = function Future$chain(f){ | ||
if(!isFuture(this)) error$invalidContext('Future#chain', this); | ||
if(!isFunction(f)) error$invalidArgument('Future#chain', 0, 'be a function', f); | ||
if(!isFuture(this)) invalidContext('Future#chain', this); | ||
if(!isFunction(f)) invalidArgument('Future#chain', 0, 'be a function', f); | ||
return new FutureChain(this, f); | ||
@@ -230,4 +193,4 @@ }; | ||
Future.prototype.chainRej = function Future$chainRej(f){ | ||
if(!isFuture(this)) error$invalidContext('Future.chainRej', this); | ||
if(!isFunction(f)) error$invalidArgument('Future.chainRej', 0, 'a function', f); | ||
if(!isFuture(this)) invalidContext('Future.chainRej', this); | ||
if(!isFunction(f)) invalidArgument('Future.chainRej', 0, 'a function', f); | ||
return new FutureChainRej(this, f); | ||
@@ -237,4 +200,4 @@ }; | ||
Future.prototype.mapRej = function Future$mapRej(f){ | ||
if(!isFuture(this)) error$invalidContext('Future#mapRej', this); | ||
if(!isFunction(f)) error$invalidArgument('Future#mapRej', 0, 'be a function', f); | ||
if(!isFuture(this)) invalidContext('Future#mapRej', this); | ||
if(!isFunction(f)) invalidArgument('Future#mapRej', 0, 'be a function', f); | ||
return new FutureMapRej(this, f); | ||
@@ -244,3 +207,3 @@ }; | ||
Future.prototype.swap = function Future$swap(){ | ||
if(!isFuture(this)) error$invalidContext('Future#swap', this); | ||
if(!isFuture(this)) invalidContext('Future#swap', this); | ||
return new FutureSwap(this); | ||
@@ -250,4 +213,4 @@ }; | ||
Future.prototype.race = function Future$race(m){ | ||
if(!isFuture(this)) error$invalidContext('Future#race', this); | ||
if(!isFuture(m)) error$invalidArgument('Future#race', 0, 'be a Future', m); | ||
if(!isFuture(this)) invalidContext('Future#race', this); | ||
if(!isFuture(m)) invalidArgument('Future#race', 0, 'be a Future', m); | ||
return new FutureRace(this, m); | ||
@@ -257,4 +220,4 @@ }; | ||
Future.prototype.and = function Future$and(m){ | ||
if(!isFuture(this)) error$invalidContext('Future#and', this); | ||
if(!isFuture(m)) error$invalidArgument('Future#and', 0, 'be a Future', m); | ||
if(!isFuture(this)) invalidContext('Future#and', this); | ||
if(!isFuture(m)) invalidArgument('Future#and', 0, 'be a Future', m); | ||
return new FutureAnd(this, m); | ||
@@ -264,4 +227,4 @@ }; | ||
Future.prototype.or = function Future$or(m){ | ||
if(!isFuture(this)) error$invalidContext('Future#or', this); | ||
if(!isFuture(m)) error$invalidArgument('Future#or', 0, 'be a Future', m); | ||
if(!isFuture(this)) invalidContext('Future#or', this); | ||
if(!isFuture(m)) invalidArgument('Future#or', 0, 'be a Future', m); | ||
return new FutureOr(this, m); | ||
@@ -271,4 +234,4 @@ }; | ||
Future.prototype.both = function Future$both(m){ | ||
if(!isFuture(this)) error$invalidContext('Future#both', this); | ||
if(!isFuture(m)) error$invalidArgument('Future#both', 0, 'be a Future', m); | ||
if(!isFuture(this)) invalidContext('Future#both', this); | ||
if(!isFuture(m)) invalidArgument('Future#both', 0, 'be a Future', m); | ||
return new FutureBoth(this, m); | ||
@@ -278,5 +241,5 @@ }; | ||
Future.prototype.fold = function Future$fold(f, g){ | ||
if(!isFuture(this)) error$invalidContext('Future#fold', this); | ||
if(!isFunction(f)) error$invalidArgument('Future#fold', 0, 'be a function', f); | ||
if(!isFunction(g)) error$invalidArgument('Future#fold', 1, 'be a function', g); | ||
if(!isFuture(this)) invalidContext('Future#fold', this); | ||
if(!isFunction(f)) invalidArgument('Future#fold', 0, 'be a function', f); | ||
if(!isFunction(g)) invalidArgument('Future#fold', 1, 'be a function', g); | ||
return new FutureFold(this, f, g); | ||
@@ -286,5 +249,5 @@ }; | ||
Future.prototype.hook = function Future$hook(dispose, consume){ | ||
if(!isFuture(this)) error$invalidContext('Future#hook', this); | ||
if(!isFunction(dispose)) error$invalidArgument('Future#hook', 0, 'be a function', dispose); | ||
if(!isFunction(consume)) error$invalidArgument('Future#hook', 1, 'be a function', consume); | ||
if(!isFuture(this)) invalidContext('Future#hook', this); | ||
if(!isFunction(dispose)) invalidArgument('Future#hook', 0, 'be a function', dispose); | ||
if(!isFunction(consume)) invalidArgument('Future#hook', 1, 'be a function', consume); | ||
return new FutureHook(this, dispose, consume); | ||
@@ -294,4 +257,4 @@ }; | ||
Future.prototype.finally = function Future$finally(m){ | ||
if(!isFuture(this)) error$invalidContext('Future#finally', this); | ||
if(!isFuture(m)) error$invalidArgument('Future#finally', 0, 'be a Future', m); | ||
if(!isFuture(this)) invalidContext('Future#finally', this); | ||
if(!isFuture(m)) invalidArgument('Future#finally', 0, 'be a Future', m); | ||
return new FutureFinally(this, m); | ||
@@ -301,3 +264,3 @@ }; | ||
Future.prototype.cache = function Future$cache(){ | ||
if(!isFuture(this)) error$invalidContext('Future#cache', this); | ||
if(!isFuture(this)) invalidContext('Future#cache', this); | ||
return new CachedFuture(this); | ||
@@ -307,5 +270,5 @@ }; | ||
Future.prototype.fork = function Future$fork(rej, res){ | ||
if(!isFuture(this)) error$invalidContext('Future#fork', this); | ||
if(!isFunction(rej)) error$invalidArgument('Future#fork', 0, 'be a function', rej); | ||
if(!isFunction(res)) error$invalidArgument('Future#fork', 1, 'be a function', res); | ||
if(!isFuture(this)) invalidContext('Future#fork', this); | ||
if(!isFunction(rej)) invalidArgument('Future#fork', 0, 'be a function', rej); | ||
if(!isFunction(res)) invalidArgument('Future#fork', 1, 'be a function', res); | ||
return this._f(rej, res); | ||
@@ -315,4 +278,4 @@ }; | ||
Future.prototype.value = function Future$value(f){ | ||
if(!isFuture(this)) error$invalidContext('Future#value', this); | ||
if(!isFunction(f)) error$invalidArgument('Future#value', 0, 'be a function', f); | ||
if(!isFuture(this)) invalidContext('Future#value', this); | ||
if(!isFunction(f)) invalidArgument('Future#value', 0, 'be a function', f); | ||
return this._f(function Future$value$rej(e){ | ||
@@ -326,3 +289,3 @@ throw new Error( | ||
Future.prototype.promise = function Future$promise(){ | ||
if(!isFuture(this)) error$invalidContext('Future#promise', this); | ||
if(!isFuture(this)) invalidContext('Future#promise', this); | ||
const _this = this; | ||
@@ -340,3 +303,3 @@ return new Promise(function Future$promise$do(resolve, reject){ | ||
function ap$mval(mval, mfunc){ | ||
if(!Z.Apply.test(mfunc)) error$invalidArgument('Future.ap', 1, 'be an Apply', mfunc); | ||
if(!Z.Apply.test(mfunc)) invalidArgument('Future.ap', 1, 'be an Apply', mfunc); | ||
return Z.ap(mval, mfunc); | ||
@@ -346,3 +309,3 @@ } | ||
Future.ap = function ap(mval, mfunc){ | ||
if(!Z.Apply.test(mval)) error$invalidArgument('Future.ap', 0, 'be an Apply', mval); | ||
if(!Z.Apply.test(mval)) invalidArgument('Future.ap', 0, 'be an Apply', mval); | ||
if(arguments.length === 1) return unaryPartial(ap$mval, mval); | ||
@@ -353,3 +316,3 @@ return ap$mval(mval, mfunc); | ||
function map$mapper(mapper, m){ | ||
if(!Z.Functor.test(m)) error$invalidArgument('Future.map', 1, 'be a Functor', m); | ||
if(!Z.Functor.test(m)) invalidArgument('Future.map', 1, 'be a Functor', m); | ||
return Z.map(mapper, m); | ||
@@ -359,3 +322,3 @@ } | ||
Future.map = function map(mapper, m){ | ||
if(!isFunction(mapper)) error$invalidArgument('Future.map', 0, 'be a Function', mapper); | ||
if(!isFunction(mapper)) invalidArgument('Future.map', 0, 'be a Function', mapper); | ||
if(arguments.length === 1) return unaryPartial(map$mapper, mapper); | ||
@@ -366,3 +329,3 @@ return map$mapper(mapper, m); | ||
function bimap$lmapper$rmapper(lmapper, rmapper, m){ | ||
if(!Z.Bifunctor.test(m)) error$invalidArgument('Future.bimap', 2, 'be a Bifunctor', m); | ||
if(!Z.Bifunctor.test(m)) invalidArgument('Future.bimap', 2, 'be a Bifunctor', m); | ||
return Z.bimap(lmapper, rmapper, m); | ||
@@ -372,3 +335,3 @@ } | ||
function bimap$lmapper(lmapper, rmapper, m){ | ||
if(!isFunction(rmapper)) error$invalidArgument('Future.bimap', 1, 'be a Function', rmapper); | ||
if(!isFunction(rmapper)) invalidArgument('Future.bimap', 1, 'be a Function', rmapper); | ||
if(arguments.length === 2) return binaryPartial(bimap$lmapper$rmapper, lmapper, rmapper); | ||
@@ -379,3 +342,3 @@ return bimap$lmapper$rmapper(lmapper, rmapper, m); | ||
Future.bimap = function bimap(lmapper, rmapper, m){ | ||
if(!isFunction(lmapper)) error$invalidArgument('Future.bimap', 0, 'be a Function', lmapper); | ||
if(!isFunction(lmapper)) invalidArgument('Future.bimap', 0, 'be a Function', lmapper); | ||
if(arguments.length === 1) return unaryPartial(bimap$lmapper, lmapper); | ||
@@ -387,3 +350,3 @@ if(arguments.length === 2) return bimap$lmapper(lmapper, rmapper); | ||
function chain$chainer(chainer, m){ | ||
if(!Z.Chain.test(m)) error$invalidArgument('Future.chain', 1, 'be a Chain', m); | ||
if(!Z.Chain.test(m)) invalidArgument('Future.chain', 1, 'be a Chain', m); | ||
return Z.chain(chainer, m); | ||
@@ -393,3 +356,3 @@ } | ||
Future.chain = function chain(chainer, m){ | ||
if(!isFunction(chainer)) error$invalidArgument('Future.chain', 0, 'be a Function', chainer); | ||
if(!isFunction(chainer)) invalidArgument('Future.chain', 0, 'be a Function', chainer); | ||
if(arguments.length === 1) return unaryPartial(chain$chainer, chainer); | ||
@@ -400,3 +363,3 @@ return chain$chainer(chainer, m); | ||
function and$left(left, right){ | ||
if(!isFuture(right)) error$invalidArgument('Future.and', 1, 'be a Future', right); | ||
if(!isFuture(right)) invalidArgument('Future.and', 1, 'be a Future', right); | ||
return new FutureAnd(left, right); | ||
@@ -406,3 +369,3 @@ } | ||
Future.and = function and(left, right){ | ||
if(!isFuture(left)) error$invalidArgument('Future.and', 0, 'be a Future', left); | ||
if(!isFuture(left)) invalidArgument('Future.and', 0, 'be a Future', left); | ||
if(arguments.length === 1) return unaryPartial(and$left, left); | ||
@@ -413,3 +376,3 @@ return and$left(left, right); | ||
function both$left(left, right){ | ||
if(!isFuture(right)) error$invalidArgument('Future.both', 1, 'be a Future', right); | ||
if(!isFuture(right)) invalidArgument('Future.both', 1, 'be a Future', right); | ||
return new FutureBoth(left, right); | ||
@@ -419,3 +382,3 @@ } | ||
Future.both = function both(left, right){ | ||
if(!isFuture(left)) error$invalidArgument('Future.both', 0, 'be a Future', left); | ||
if(!isFuture(left)) invalidArgument('Future.both', 0, 'be a Future', left); | ||
if(arguments.length === 1) return unaryPartial(both$left, left); | ||
@@ -434,3 +397,3 @@ return both$left(left, right); | ||
Future.after = function Future$after(n, x){ | ||
if(!isPositiveInteger(n)) error$invalidArgument('Future.after', 0, 'be a positive integer', n); | ||
if(!isPositiveInteger(n)) invalidArgument('Future.after', 0, 'be a positive integer', n); | ||
if(arguments.length === 1) return unaryPartial(Future$after$n, n); | ||
@@ -445,3 +408,3 @@ return Future$after$n(n, x); | ||
Future.rejectAfter = function rejectAfter(time, reason){ | ||
if(!isPositiveInteger(time)) error$invalidArgument( | ||
if(!isPositiveInteger(time)) invalidArgument( | ||
'Future.rejectAfter', 0, 'be a positive integer', time | ||
@@ -453,14 +416,4 @@ ); | ||
Future.cast = function Future$cast(m){ | ||
deprecate('Future.cast() is deprecated. Please use Future((l, r) => {m.fork(l, r)})'); | ||
return new SafeFuture((l, r) => void m.fork(l, r)); | ||
}; | ||
Future.fromForkable = function Future$fromForkable(m){ | ||
deprecate('Future.fromForkable() is deprecated. Please use Future((l, r) => {m.fork(l, r)})'); | ||
return new SafeFuture((l, r) => void m.fork(l, r)); | ||
}; | ||
Future.try = function Future$try(f){ | ||
if(!isFunction(f)) error$invalidArgument('Future.try', 0, 'be a function', f); | ||
if(!isFunction(f)) invalidArgument('Future.try', 0, 'be a function', f); | ||
return new FutureTry(f); | ||
@@ -471,3 +424,3 @@ }; | ||
if(arguments.length === 1) return unaryPartial(Future$encase, f); | ||
if(!isFunction(f)) error$invalidArgument('Future.encase', 0, 'be a function', f); | ||
if(!isFunction(f)) invalidArgument('Future.encase', 0, 'be a function', f); | ||
return new FutureEncase(f, x); | ||
@@ -481,4 +434,4 @@ }; | ||
default: | ||
if(!isFunction(f)) error$invalidArgument('Future.encase2', 0, 'be a function', f); | ||
if(!isBinary(f)) error$invalidArgument('Future.encase2', 0, 'take two arguments', f); | ||
if(!isFunction(f)) invalidArgument('Future.encase2', 0, 'be a function', f); | ||
if(!isBinary(f)) invalidArgument('Future.encase2', 0, 'take two arguments', f); | ||
return new FutureEncase(f, x, y); | ||
@@ -494,4 +447,4 @@ } | ||
default: | ||
if(!isFunction(f)) error$invalidArgument('Future.encase3', 0, 'be a function', f); | ||
if(!isTernary(f)) error$invalidArgument('Future.encase3', 0, 'take three arguments', f); | ||
if(!isFunction(f)) invalidArgument('Future.encase3', 0, 'be a function', f); | ||
if(!isTernary(f)) invalidArgument('Future.encase3', 0, 'take three arguments', f); | ||
return new FutureEncase(f, x, y, z); | ||
@@ -503,3 +456,3 @@ } | ||
if(arguments.length === 1) return unaryPartial(Future$fromPromise, f); | ||
if(!isFunction(f)) error$invalidArgument('Future.fromPromise', 0, 'be a function', f); | ||
if(!isFunction(f)) invalidArgument('Future.fromPromise', 0, 'be a function', f); | ||
return new FutureFromPromise(f, x); | ||
@@ -513,4 +466,4 @@ }; | ||
default: | ||
if(!isFunction(f)) error$invalidArgument('Future.fromPromise2', 0, 'be a function', f); | ||
if(!isBinary(f)) error$invalidArgument('Future.fromPromise2', 0, 'take two arguments', f); | ||
if(!isFunction(f)) invalidArgument('Future.fromPromise2', 0, 'be a function', f); | ||
if(!isBinary(f)) invalidArgument('Future.fromPromise2', 0, 'take two arguments', f); | ||
return new FutureFromPromise(f, x, y); | ||
@@ -527,5 +480,5 @@ } | ||
if(!isFunction(f)) | ||
error$invalidArgument('Future.fromPromise3', 0, 'be a function', f); | ||
invalidArgument('Future.fromPromise3', 0, 'be a function', f); | ||
if(!isTernary(f)) | ||
error$invalidArgument('Future.fromPromise3', 0, 'take three arguments', f); | ||
invalidArgument('Future.fromPromise3', 0, 'take three arguments', f); | ||
return new FutureFromPromise(f, x, y, z); | ||
@@ -536,35 +489,167 @@ } | ||
Future.node = function Future$node(f){ | ||
if(!isFunction(f)) error$invalidArgument('Future.node', 0, 'be a function', f); | ||
if(!isFunction(f)) invalidArgument('Future.node', 0, 'be a function', f); | ||
return new FutureNode(f); | ||
}; | ||
Future.parallel = function Future$parallel(i, ms){ | ||
if(arguments.length === 1) return unaryPartial(Future$parallel, i); | ||
if(!isPositiveInteger(i)) | ||
error$invalidArgument('Future.parallel', 0, 'be a positive integer', i); | ||
if(!Array.isArray(ms)) | ||
error$invalidArgument('Future.parallel', 1, 'be an array', ms); | ||
function parallel$i(i, ms){ | ||
if(!Array.isArray(ms)) invalidArgument('Future.parallel', 1, 'be an array', ms); | ||
return new FutureParallel(i, ms); | ||
} | ||
Future.parallel = function parallel(i, ms){ | ||
if(!isPositiveInteger(i)) invalidArgument('Future.parallel', 0, 'be a positive integer', i); | ||
if(arguments.length === 1) return unaryPartial(parallel$i, i); | ||
return parallel$i(i, ms); | ||
}; | ||
Future.do = function Future$do(f){ | ||
if(!isFunction(f)) error$invalidArgument('Future.do', 0, 'be a function', f); | ||
if(!isFunction(f)) invalidArgument('Future.do', 0, 'be a function', f); | ||
return new FutureDo(f); | ||
}; | ||
Future.chainRej = createUnaryDispatcher('chainRej'); | ||
Future.mapRej = createUnaryDispatcher('mapRej'); | ||
Future.swap = createNullaryDispatcher('swap'); | ||
Future.fork = createBinaryDispatcher('fork'); | ||
Future.race = createUnaryDispatcher('race'); | ||
Future.or = createUnaryDispatcher('or'); | ||
Future.fold = createBinaryDispatcher('fold'); | ||
Future.hook = createInvertedBinaryDispatcher('hook'); | ||
Future.finally = createUnaryDispatcher('finally'); | ||
Future.value = createUnaryDispatcher('value'); | ||
Future.promise = createNullaryDispatcher('promise'); | ||
Future.cache = createNullaryDispatcher('cache'); | ||
Future.extractLeft = createNullaryDispatcher('extractLeft'); | ||
Future.extractRight = createNullaryDispatcher('extractRight'); | ||
function chainRej$chainer(chainer, m){ | ||
if(!isFuture(m)) invalidArgument('Future.chainRej', 1, 'be a Future', m); | ||
return new FutureChainRej(m, chainer); | ||
} | ||
Future.chainRej = function chainRej(chainer, m){ | ||
if(!isFunction(chainer)) invalidArgument('Future.chainRej', 0, 'be a Function', chainer); | ||
if(arguments.length === 1) return unaryPartial(chainRej$chainer, chainer); | ||
return chainRej$chainer(chainer, m); | ||
}; | ||
function mapRej$mapper(mapper, m){ | ||
if(!isFuture(m)) invalidArgument('Future.mapRej', 1, 'be a Future', m); | ||
return new FutureMapRej(m, mapper); | ||
} | ||
Future.mapRej = function mapRej(mapper, m){ | ||
if(!isFunction(mapper)) invalidArgument('Future.mapRej', 0, 'be a Function', mapper); | ||
if(arguments.length === 1) return unaryPartial(mapRej$mapper, mapper); | ||
return mapRej$mapper(mapper, m); | ||
}; | ||
function race$right(right, left){ | ||
if(!isFuture(left)) invalidArgument('Future.race', 1, 'be a Future', left); | ||
return new FutureRace(left, right); | ||
} | ||
Future.race = function race(right, left){ | ||
if(!isFuture(right)) invalidArgument('Future.race', 0, 'be a Future', right); | ||
if(arguments.length === 1) return unaryPartial(race$right, right); | ||
return race$right(right, left); | ||
}; | ||
function or$left(left, right){ | ||
if(!isFuture(right)) invalidArgument('Future.or', 1, 'be a Future', right); | ||
return new FutureOr(left, right); | ||
} | ||
Future.or = function or(left, right){ | ||
if(!isFuture(left)) invalidArgument('Future.or', 0, 'be a Future', left); | ||
if(arguments.length === 1) return unaryPartial(or$left, left); | ||
return or$left(left, right); | ||
}; | ||
function finally$right(right, left){ | ||
if(!isFuture(left)) invalidArgument('Future.finally', 1, 'be a Future', left); | ||
return new FutureFinally(left, right); | ||
} | ||
Future.finally = function finally$(right, left){ | ||
if(!isFuture(right)) invalidArgument('Future.finally', 0, 'be a Future', right); | ||
if(arguments.length === 1) return unaryPartial(finally$right, right); | ||
return finally$right(right, left); | ||
}; | ||
function value$cont(cont, m){ | ||
if(!isFuture(m)) invalidArgument('Future.value', 1, 'be a Future', m); | ||
return m.value(cont); | ||
} | ||
Future.value = function value(cont, m){ | ||
if(!isFunction(cont)) invalidArgument('Future.value', 0, 'be a Function', cont); | ||
if(arguments.length === 1) return unaryPartial(value$cont, cont); | ||
return value$cont(cont, m); | ||
}; | ||
Future.swap = function swap(m){ | ||
if(!isFuture(m)) invalidArgument('Future.swap', 0, 'be a Future', m); | ||
return new FutureSwap(m); | ||
}; | ||
Future.promise = function promise(m){ | ||
if(!isFuture(m)) invalidArgument('Future.promise', 0, 'be a Future', m); | ||
return m.promise(); | ||
}; | ||
Future.cache = function cache(m){ | ||
if(!isFuture(m)) invalidArgument('Future.cache', 0, 'be a Future', m); | ||
return new CachedFuture(m); | ||
}; | ||
Future.extractLeft = function extractLeft(m){ | ||
if(!isFuture(m)) invalidArgument('Future.extractLeft', 0, 'be a Future', m); | ||
return m.extractLeft(); | ||
}; | ||
Future.extractRight = function extractRight(m){ | ||
if(!isFuture(m)) invalidArgument('Future.extractRight', 0, 'be a Future', m); | ||
return m.extractRight(); | ||
}; | ||
function fork$f$g(f, g, m){ | ||
if(!isFuture(m)) invalidArgument('Future.fork', 2, 'be a Future', m); | ||
return m._f(f, g); | ||
} | ||
function fork$f(f, g, m){ | ||
if(!isFunction(g)) invalidArgument('Future.fork', 1, 'be a function', g); | ||
if(arguments.length === 2) return binaryPartial(fork$f$g, f, g); | ||
return fork$f$g(f, g, m); | ||
} | ||
Future.fork = function fork(f, g, m){ | ||
if(!isFunction(f)) invalidArgument('Future.fork', 0, 'be a function', f); | ||
if(arguments.length === 1) return unaryPartial(fork$f, f); | ||
if(arguments.length === 2) return fork$f(f, g); | ||
return fork$f(f, g, m); | ||
}; | ||
function fold$f$g(f, g, m){ | ||
if(!isFuture(m)) invalidArgument('Future.fold', 2, 'be a Future', m); | ||
return new FutureFold(m, f, g); | ||
} | ||
function fold$f(f, g, m){ | ||
if(!isFunction(g)) invalidArgument('Future.fold', 1, 'be a function', g); | ||
if(arguments.length === 2) return binaryPartial(fold$f$g, f, g); | ||
return fold$f$g(f, g, m); | ||
} | ||
Future.fold = function fold(f, g, m){ | ||
if(!isFunction(f)) invalidArgument('Future.fold', 0, 'be a function', f); | ||
if(arguments.length === 1) return unaryPartial(fold$f, f); | ||
if(arguments.length === 2) return fold$f(f, g); | ||
return fold$f(f, g, m); | ||
}; | ||
function hook$acquire$cleanup(acquire, cleanup, consume){ | ||
if(!isFunction(consume)) invalidArgument('Future.hook', 2, 'be a Future', consume); | ||
return new FutureHook(acquire, cleanup, consume); | ||
} | ||
function hook$acquire(acquire, cleanup, consume){ | ||
if(!isFunction(cleanup)) invalidArgument('Future.hook', 1, 'be a function', cleanup); | ||
if(arguments.length === 2) return binaryPartial(hook$acquire$cleanup, acquire, cleanup); | ||
return hook$acquire$cleanup(acquire, cleanup, consume); | ||
} | ||
Future.hook = function hook(acquire, cleanup, consume){ | ||
if(!isFuture(acquire)) invalidArgument('Future.hook', 0, 'be a Future', acquire); | ||
if(arguments.length === 1) return unaryPartial(hook$acquire, acquire); | ||
if(arguments.length === 2) return hook$acquire(acquire, cleanup); | ||
return hook$acquire(acquire, cleanup, consume); | ||
}; | ||
//Utilities. | ||
@@ -574,3 +659,2 @@ Future.util = { | ||
Done, | ||
isForkable, | ||
isFuture, | ||
@@ -982,3 +1066,3 @@ isThenable, | ||
function check$do$g(g){ | ||
if(!isIterator(g)) error$invalidArgument( | ||
if(!isIterator(g)) invalidArgument( | ||
'Future.do', 0, 'return an iterator, maybe you forgot the "*"', g | ||
@@ -1291,2 +1375,41 @@ ); | ||
function FutureParallelAp(mval, mfunc){ | ||
this._mval = mval; | ||
this._mfunc = mfunc; | ||
} | ||
FutureParallelAp.prototype = Object.create(Future.prototype); | ||
FutureParallelAp.prototype._f = function FutureParallelAp$fork(rej, res){ | ||
let func, val, okval = false, okfunc = false, rejected = false, c1, c2; | ||
function FutureParallelAp$rej(x){ | ||
if(!rejected){ | ||
rejected = true; | ||
rej(x); | ||
} | ||
} | ||
c1 = this._mval._f(FutureParallelAp$rej, function FutureParallelAp$fork$resVal(x){ | ||
c1 = noop; | ||
if(!okval) return void (okfunc = true, val = x); | ||
check$ap$f(func); | ||
res(func(x)); | ||
}); | ||
c2 = this._mfunc._f(FutureParallelAp$rej, function FutureParallelAp$fork$resFunc(f){ | ||
c2 = noop; | ||
if(!okfunc) return void (okval = true, func = f); | ||
check$ap$f(f); | ||
res(f(val)); | ||
}); | ||
return function FutureParallelAp$fork$cancel(){ | ||
c1(); | ||
c2(); | ||
}; | ||
}; | ||
FutureParallelAp.prototype.toString = function FutureParallelAp$toString(){ | ||
return `new FutureParallelAp(${this._mval.toString()}, ${this._mfunc.toString()})`; | ||
}; | ||
//---------- | ||
function FutureSwap(parent){ | ||
@@ -1493,5 +1616,5 @@ this._parent = parent; | ||
function FutureFinally(left, right){ | ||
this._left = left; | ||
this._right = right; | ||
function FutureFinally(computation, cleanup){ | ||
this._computation = computation; | ||
this._cleanup = cleanup; | ||
} | ||
@@ -1504,14 +1627,35 @@ | ||
let cancel; | ||
const r = _this._left._f(function FutureFinally$fork$rej(e){ | ||
cancel = _this._right._f(rej, function FutureFinally$fork$rej$res(){ rej(e) }); | ||
const cancelComputation = _this._computation._f(function FutureFinally$fork$rej(e){ | ||
cancel = _this._cleanup._f(rej, function FutureFinally$fork$rej$res(){ rej(e) }); | ||
}, function FutureFinally$fork$res(x){ | ||
cancel = _this._right._f(rej, function FutureFinally$fork$res$res(){ res(x) }); | ||
cancel = _this._cleanup._f(rej, function FutureFinally$fork$res$res(){ res(x) }); | ||
}); | ||
return cancel || (cancel = r, function FutureFinally$fork$cancel(){ cancel() }); | ||
if(cancel) return cancel; | ||
cancel = function FutureFinally$fork$cancelBoth(){ | ||
cancelComputation(); | ||
_this._cleanup._f(noop, noop)(); | ||
}; | ||
return function FutureFinally$fork$cancel(){ cancel() }; | ||
}; | ||
FutureFinally.prototype.toString = function FutureFinally$toString(){ | ||
return `${this._left.toString()}.finally(${this._right.toString()})`; | ||
return `${this._computation.toString()}.finally(${this._cleanup.toString()})`; | ||
}; | ||
//---------- | ||
function FutureNever(){} | ||
FutureNever.prototype = Object.create(Future.prototype); | ||
FutureNever.prototype._f = function FutureNever$fork(){ | ||
return noop; | ||
}; | ||
FutureNever.prototype.toString = function FutureNever$toString(){ | ||
return 'Future.never'; | ||
}; | ||
Future.never = new FutureNever; | ||
Future.classes = { | ||
@@ -1537,2 +1681,3 @@ SafeFuture, | ||
FutureAp, | ||
FutureParallelAp, | ||
FutureSwap, | ||
@@ -1545,7 +1690,26 @@ FutureRace, | ||
FutureHook, | ||
FutureFinally | ||
FutureFinally, | ||
FutureNever | ||
}; | ||
////////////// | ||
// Parallel // | ||
////////////// | ||
const ParallelFuture = concurrify(Future, Future.never, Future.race, function(mval, mfunc){ | ||
return new FutureParallelAp(mval, mfunc); | ||
}); | ||
function isParallel(x){ | ||
return x instanceof ParallelFuture || type(x) === ParallelFuture['@@type']; | ||
} | ||
Future.Par = ParallelFuture; | ||
Future.seq = function seq(par){ | ||
if(!isParallel(par)) invalidArgument('Future.seq', 0, 'to be a Par', par); | ||
return par.sequential; | ||
}; | ||
return Future; | ||
})); |
{ | ||
"name": "fluture", | ||
"version": "4.3.5", | ||
"version": "5.0.0", | ||
"description": "FantasyLand compliant (monadic) alternative to Promises", | ||
@@ -55,4 +55,6 @@ "main": "fluture.js", | ||
"dependencies": { | ||
"concurrify": "^0.1.0", | ||
"inspect-f": "^1.2.0", | ||
"sanctuary-type-classes": "^3.0.0" | ||
"sanctuary-type-classes": "^3.0.0", | ||
"sanctuary-type-identifiers": "^1.0.0" | ||
}, | ||
@@ -80,5 +82,4 @@ "devDependencies": { | ||
"rimraf": "^2.4.3", | ||
"sanctuary": "^0.11.1", | ||
"xyz": "^2.0.1" | ||
} | ||
} |
@@ -16,3 +16,3 @@ # [![Fluture](logo.png)](#butterfly) | ||
Fluture boasts the following features: | ||
Some of the features provided by Fluture include: | ||
@@ -23,3 +23,2 @@ * [Cancellation](#future). | ||
* A pleasant debugging experience through informative error messages. | ||
* Considerable performance benefits over Promises and the likes. | ||
@@ -61,2 +60,3 @@ For more information: | ||
* [of](#of) | ||
* [never](#never) | ||
* [reject](#reject) | ||
@@ -93,2 +93,3 @@ * [after](#after) | ||
* [parallel](#parallel) | ||
* [ConcurrentFuture](#concurrentfuture) | ||
1. [Utility functions](#utility-functions) | ||
@@ -180,2 +181,8 @@ * [isFuture](#isfuture) | ||
#### never | ||
##### `.never :: Future a a` | ||
A Future that never settles. Can be useful as an initial value when reducing | ||
with [`race`](#race), for example. | ||
#### reject | ||
@@ -550,2 +557,6 @@ ##### `.reject :: a -> Future a _` | ||
As with [`hook`](#hook); when the Future is cancelled before the *finally | ||
computation* is running, the *finally computation* is executed and immediately | ||
cancelled. | ||
### Consuming Futures | ||
@@ -640,3 +651,3 @@ | ||
const first = futures => futures.reduce(race); | ||
const first = futures => futures.reduce(Future.race, Future.never); | ||
first([ | ||
@@ -669,2 +680,7 @@ Future.after(100, 'hello'), | ||
const result = isResolved().and(getValue()); | ||
//Asynchronous "all", where the resulting Future will be the leftmost to reject: | ||
const all = ms => ms.reduce(Future.and, Future.of(true)); | ||
all([Future.after(20, 1), Future.of(2)]).value(console.log); | ||
//> 2 | ||
``` | ||
@@ -690,9 +706,6 @@ | ||
const program = S.pipe([ | ||
reject, | ||
or(of('second chance')), | ||
value(console.log) | ||
]); | ||
program('first chance') | ||
> "second chance" | ||
//Asynchronous "any", where the resulting Future will be the leftmost to resolve: | ||
const any = ms => ms.reduce(Future.or, Future.reject('empty list')); | ||
any([Future.reject(1), Future.after(20, 2), Future.of(3)]).value(console.log); | ||
//> 2 | ||
``` | ||
@@ -759,2 +772,39 @@ | ||
#### ConcurrentFuture | ||
##### `.Par :: Future a b -> ConcurrentFuture a b` | ||
##### `.seq :: ConcurrentFuture a b -> Future a b` | ||
ConcurrentFuture (or `Par` for short) is the result of applying | ||
[`concurrify`][concurrify] to `Future`. It provides a mechanism for constructing | ||
a [FantasyLand `Alternative`][FL:alternative] from a member of `Future`. This | ||
allows Futures to benefit from the Alternative Interface, which includes | ||
parallel `ap`, `zero` and `alt`. | ||
The idea is that you can switch back and forth between `Future` and | ||
`ConcurrentFuture`, using `Par` and `seq`, to get sequential or concurrent | ||
behaviour respectively. It's useful if you want a purely algebraic alternative | ||
to [`parallel`](#parallel) and [`race`](#race). | ||
```js | ||
const {of, ap, zero, alt, sequence} = require('sanctuary'); | ||
const {Future, Par, seq} = require('fluture'); | ||
//Some dummy values | ||
const x = 1; | ||
const f = a => a + 1; | ||
//The following two are equal ways to construct a ConcurrentFuture | ||
const parx = of(Par, x); | ||
const parf = Par(of(Future, f)); | ||
//We can make use of parallel apply | ||
seq(ap(parx, parf)).value(console.log) //> 2 | ||
//Or concurrent sequencing | ||
seq(sequence(Par, [parx, parf])).value(console.log) //> [x, f] | ||
//Or racing with alternative | ||
seq(alt(zero(Par), parx)).value(console.log) //> 1 | ||
``` | ||
### Utility functions | ||
@@ -908,7 +958,4 @@ | ||
Simply run `node ./bench/<file>` to see how a specific method compares to | ||
implementations in `data.task`, `ramda-fantasy.Future` and `Promise`*. | ||
implementations in `data.task` and `ramda-fantasy.Future`. | ||
\* Promise is not included in all benchmarks because it tends to make the | ||
process run out of memory. | ||
## Butterfly | ||
@@ -935,2 +982,3 @@ | ||
[FL3]: https://github.com/fantasyland/fantasy-land | ||
[FL:alternative]: https://github.com/fantasyland/fantasy-land#alternative | ||
[FL:functor]: https://github.com/fantasyland/fantasy-land#functor | ||
@@ -956,2 +1004,4 @@ [FL:chain]: https://github.com/fantasyland/fantasy-land#chain | ||
[concurrify]: https://github.com/fluture-js/concurrify | ||
[1]: https://github.com/futurize/futurize | ||
@@ -958,0 +1008,0 @@ [2]: https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch7.html |
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
142824
21
2806
1002
4
+ Addedconcurrify@^0.1.0
+ Addedconcurrify@0.1.2(transitive)
+ Addedsanctuary-type-classes@4.0.0(transitive)