Module
Common Functional Programming Algebraic data types for JavaScript that is compatible with most modern browsers and Deno.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162import { factorizeType } from "./SumType.js";import Either from "./Either.js";
export const Task = factorizeType("Task", [ "asyncFunction" ]);
// from :: Task => f -> T fTask.from = (composedFunction) => Task(composedFunction);
// wrap :: Task t => (* -> Promise a) -> t e Promise aTask.wrap = asyncFunction => { let promise; const proxyFunction = function (...argumentList) { promise = promise || asyncFunction.call(null, ...argumentList);
return promise.then( maybeContainer => Either.is(maybeContainer) ? maybeContainer : Either.Right(maybeContainer), maybeContainer => Either.is(maybeContainer) ? maybeContainer : Either.Left(maybeContainer) ); };
return Task( Object.defineProperty( proxyFunction, 'length', { value: asyncFunction.length } ) );};
// empty :: Task t => () => tTask.empty = Task.prototype.empty = Task.prototype["fantasy-land/empty"] = _ => Task(_ => function () {});
// of :: Task t => a -> t aTask.of = Task.prototype.of = Task.prototype["fantasy-land/of"] = unaryFunction => Task(_ => Promise.resolve(Either.Right(unaryFunction)));
// ap :: Task a ~> Task (a -> b) -> Task bTask.prototype.ap = Task.prototype["fantasy-land/ap"] = function (container) {
return Task(_ => { const maybePromiseUnaryFunction = this.asyncFunction(); const maybePromiseValue = container.asyncFunction();
return Promise.all([ (maybePromiseUnaryFunction instanceof Promise) ? maybePromiseUnaryFunction : Promise.resolve(maybePromiseUnaryFunction), (maybePromiseValue instanceof Promise) ? maybePromiseValue : Promise.resolve(maybePromiseValue) ]) .then(([ maybeApplicativeUnaryFunction, maybeContainerValue ]) => {
return ( (Reflect.getPrototypeOf(maybeApplicativeUnaryFunction).ap) ? maybeApplicativeUnaryFunction : Either.Right(maybeApplicativeUnaryFunction) ).ap( (Reflect.getPrototypeOf(maybeContainerValue).ap) ? maybeContainerValue : Either.Right(maybeContainerValue) ); }); });};
// chain :: Task e a ~> (a -> Task b) -> Task e bTask.prototype.chain = Task.prototype["fantasy-land/chain"] = function (unaryFunction) {
return Task(_ => { const maybePromise = this.asyncFunction();
return ( (maybePromise instanceof Promise) ? maybePromise : Promise.resolve(maybePromise) ) .then(maybeContainer => (Either.is(maybeContainer) ? maybeContainer : Either.Right(maybeContainer)) .chain( value => { const maybePromise = unaryFunction(value).run();
return ( (maybePromise instanceof Promise) ? maybePromise : Promise.resolve(maybePromise) ) .then( maybeContainer => Either.is(maybeContainer) ? maybeContainer : Either.Right(maybeContainer), maybeContainer => Either.is(maybeContainer) ? maybeContainer : Either.Left(maybeContainer), ) }) ) .catch(Either.Left); });};
// map :: Task e a ~> (a -> b) -> Task e bTask.prototype.map = Task.prototype["fantasy-land/map"] = function (unaryFunction) {
return Task(_ => { const promise = this.asyncFunction();
return promise.then( container => container.chain( value => { const maybeContainer = unaryFunction(value);
return (Either.is(maybeContainer)) ? maybeContainer : Either.Right(maybeContainer); } ), Either.Left ); });};
Task.prototype.then = function (unaryFunction) {
return Task(_ => { const promise = this.asyncFunction();
return (promise instanceof Promise) ? promise.then( container => Either.Right(container.fold({ Right: unaryFunction, Left: _ => container })), Either.Left.of ) : unaryFunction(promise); });};
Task.prototype.catch = function (unaryFunction) {
return Task(_ => { const value = this.asyncFunction();
return (value instanceof Promise) ? value.then( Either.Right.of, container => ( Either.Left.is(container) ? container : Either.Left(container) ).fold({ Right: _ => container, Left: unaryFunction }),
) : unaryFunction(value); });};
// run :: Task a ~> () -> Promise bTask.prototype.run = async function () { const maybePromise = this.asyncFunction();
return ((maybePromise instanceof Promise) ? maybePromise : Promise.resolve(maybePromise)) .then( maybeContainer => Either.is(maybeContainer) ? maybeContainer : Either.Right(maybeContainer), maybeContainer => Either.is(maybeContainer) ? maybeContainer : Either.Left(maybeContainer) );};
export default Task;