fp-ts
Version:
Functional programming in TypeScript
1,276 lines (1,275 loc) • 35.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getWitherable = exports.getFilterable = exports.getApplyMonoid = exports.getApplySemigroup = exports.getSemigroup = exports.getEq = exports.getShow = exports.URI = exports.throwError = exports.sequence = exports.traverse = exports.reduceRight = exports.foldMap = exports.reduce = exports.duplicate = exports.extend = exports.alt = exports.altW = exports.flatten = exports.chainFirst = exports.chainFirstW = exports.chain = exports.chainW = exports.of = exports.apSecond = exports.apFirst = exports.ap = exports.apW = exports.mapLeft = exports.bimap = exports.map = exports.filterOrElse = exports.filterOrElseW = exports.orElse = exports.swap = exports.chainNullableK = exports.fromNullableK = exports.getOrElse = exports.getOrElseW = exports.fold = exports.fromPredicate = exports.fromOption = exports.stringifyJSON = exports.parseJSON = exports.tryCatch = exports.fromNullable = exports.right = exports.left = exports.isRight = exports.isLeft = void 0;
exports.sequenceArray = exports.traverseArray = exports.traverseArrayWithIndex = exports.apS = exports.apSW = exports.bind = exports.bindW = exports.bindTo = exports.Do = exports.exists = exports.elem = exports.toError = exports.either = exports.getValidationMonoid = exports.MonadThrow = exports.ChainRec = exports.Extend = exports.Alt = exports.Bifunctor = exports.Traversable = exports.Foldable = exports.Monad = exports.Applicative = exports.Functor = exports.getValidationSemigroup = exports.getValidation = exports.getAltValidation = exports.getApplicativeValidation = void 0;
var ChainRec_1 = require("./ChainRec");
var function_1 = require("./function");
// -------------------------------------------------------------------------------------
// guards
// -------------------------------------------------------------------------------------
/**
* Returns `true` if the either is an instance of `Left`, `false` otherwise.
*
* @category guards
* @since 2.0.0
*/
var isLeft = function (ma) { return ma._tag === 'Left'; };
exports.isLeft = isLeft;
/**
* Returns `true` if the either is an instance of `Right`, `false` otherwise.
*
* @category guards
* @since 2.0.0
*/
var isRight = function (ma) { return ma._tag === 'Right'; };
exports.isRight = isRight;
// -------------------------------------------------------------------------------------
// constructors
// -------------------------------------------------------------------------------------
/**
* Constructs a new `Either` holding a `Left` value. This usually represents a failure, due to the right-bias of this
* structure.
*
* @category constructors
* @since 2.0.0
*/
var left = function (e) { return ({ _tag: 'Left', left: e }); };
exports.left = left;
/**
* Constructs a new `Either` holding a `Right` value. This usually represents a successful value due to the right bias
* of this structure.
*
* @category constructors
* @since 2.0.0
*/
var right = function (a) { return ({ _tag: 'Right', right: a }); };
exports.right = right;
// TODO: make lazy in v3
/**
* Takes a default and a nullable value, if the value is not nully, turn it into a `Right`, if the value is nully use
* the provided default as a `Left`.
*
* @example
* import { fromNullable, left, right } from 'fp-ts/Either'
*
* const parse = fromNullable('nully')
*
* assert.deepStrictEqual(parse(1), right(1))
* assert.deepStrictEqual(parse(null), left('nully'))
*
* @category constructors
* @since 2.0.0
*/
function fromNullable(e) {
return function (a) { return (a == null ? exports.left(e) : exports.right(a)); };
}
exports.fromNullable = fromNullable;
// TODO: `onError => Lazy<A> => Either` in v3
/**
* Constructs a new `Either` from a function that might throw.
*
* @example
* import { Either, left, right, tryCatch } from 'fp-ts/Either'
*
* const unsafeHead = <A>(as: Array<A>): A => {
* if (as.length > 0) {
* return as[0]
* } else {
* throw new Error('empty array')
* }
* }
*
* const head = <A>(as: Array<A>): Either<Error, A> => {
* return tryCatch(() => unsafeHead(as), e => (e instanceof Error ? e : new Error('unknown error')))
* }
*
* assert.deepStrictEqual(head([]), left(new Error('empty array')))
* assert.deepStrictEqual(head([1, 2, 3]), right(1))
*
* @category constructors
* @since 2.0.0
*/
function tryCatch(f, onError) {
try {
return exports.right(f());
}
catch (e) {
return exports.left(onError(e));
}
}
exports.tryCatch = tryCatch;
// TODO curry in v3
/**
* Converts a JavaScript Object Notation (JSON) string into an object.
*
* @example
* import { parseJSON, toError, right, left } from 'fp-ts/Either'
*
* assert.deepStrictEqual(parseJSON('{"a":1}', toError), right({ a: 1 }))
* assert.deepStrictEqual(parseJSON('{"a":}', toError), left(new SyntaxError('Unexpected token } in JSON at position 5')))
*
* @category constructors
* @since 2.0.0
*/
function parseJSON(s, onError) {
return tryCatch(function () { return JSON.parse(s); }, onError);
}
exports.parseJSON = parseJSON;
// TODO curry in v3
/**
* Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
*
* @example
* import * as E from 'fp-ts/Either'
* import { pipe } from 'fp-ts/function'
*
* assert.deepStrictEqual(E.stringifyJSON({ a: 1 }, E.toError), E.right('{"a":1}'))
* const circular: any = { ref: null }
* circular.ref = circular
* assert.deepStrictEqual(
* pipe(
* E.stringifyJSON(circular, E.toError),
* E.mapLeft(e => e.message.includes('Converting circular structure to JSON'))
* ),
* E.left(true)
* )
*
* @category constructors
* @since 2.0.0
*/
function stringifyJSON(u, onError) {
return tryCatch(function () { return JSON.stringify(u); }, onError);
}
exports.stringifyJSON = stringifyJSON;
/**
* Derivable from `MonadThrow`.
*
* @example
* import { fromOption, left, right } from 'fp-ts/Either'
* import { pipe } from 'fp-ts/function'
* import { none, some } from 'fp-ts/Option'
*
* assert.deepStrictEqual(
* pipe(
* some(1),
* fromOption(() => 'error')
* ),
* right(1)
* )
* assert.deepStrictEqual(
* pipe(
* none,
* fromOption(() => 'error')
* ),
* left('error')
* )
*
* @category constructors
* @since 2.0.0
*/
var fromOption = function (onNone) { return function (ma) {
return ma._tag === 'None' ? exports.left(onNone()) : exports.right(ma.value);
}; };
exports.fromOption = fromOption;
/**
* Derivable from `MonadThrow`.
*
* @example
* import { fromPredicate, left, right } from 'fp-ts/Either'
* import { pipe } from 'fp-ts/function'
*
* assert.deepStrictEqual(
* pipe(
* 1,
* fromPredicate(
* (n) => n > 0,
* () => 'error'
* )
* ),
* right(1)
* )
* assert.deepStrictEqual(
* pipe(
* -1,
* fromPredicate(
* (n) => n > 0,
* () => 'error'
* )
* ),
* left('error')
* )
*
* @category constructors
* @since 2.0.0
*/
var fromPredicate = function (predicate, onFalse) { return function (a) { return (predicate(a) ? exports.right(a) : exports.left(onFalse(a))); }; };
exports.fromPredicate = fromPredicate;
// -------------------------------------------------------------------------------------
// destructors
// -------------------------------------------------------------------------------------
/**
* Takes two functions and an `Either` value, if the value is a `Left` the inner value is applied to the first function,
* if the value is a `Right` the inner value is applied to the second function.
*
* @example
* import { fold, left, right } from 'fp-ts/Either'
* import { pipe } from 'fp-ts/function'
*
* function onLeft(errors: Array<string>): string {
* return `Errors: ${errors.join(', ')}`
* }
*
* function onRight(value: number): string {
* return `Ok: ${value}`
* }
*
* assert.strictEqual(
* pipe(
* right(1),
* fold(onLeft, onRight)
* ),
* 'Ok: 1'
* )
* assert.strictEqual(
* pipe(
* left(['error 1', 'error 2']),
* fold(onLeft, onRight)
* ),
* 'Errors: error 1, error 2'
* )
*
* @category destructors
* @since 2.0.0
*/
function fold(onLeft, onRight) {
return function (ma) { return (exports.isLeft(ma) ? onLeft(ma.left) : onRight(ma.right)); };
}
exports.fold = fold;
/**
* Less strict version of [`getOrElse`](#getOrElse).
*
* @category destructors
* @since 2.6.0
*/
var getOrElseW = function (onLeft) { return function (ma) {
return exports.isLeft(ma) ? onLeft(ma.left) : ma.right;
}; };
exports.getOrElseW = getOrElseW;
/**
* Returns the wrapped value if it's a `Right` or a default value if is a `Left`.
*
* @example
* import { getOrElse, left, right } from 'fp-ts/Either'
* import { pipe } from 'fp-ts/function'
*
* assert.deepStrictEqual(
* pipe(
* right(1),
* getOrElse(() => 0)
* ),
* 1
* )
* assert.deepStrictEqual(
* pipe(
* left('error'),
* getOrElse(() => 0)
* ),
* 0
* )
*
* @category destructors
* @since 2.0.0
*/
exports.getOrElse = exports.getOrElseW;
// -------------------------------------------------------------------------------------
// combinators
// -------------------------------------------------------------------------------------
/**
* @category combinators
* @since 2.9.0
*/
function fromNullableK(e) {
var from = fromNullable(e);
return function (f) { return function () {
var a = [];
for (var _i = 0; _i < arguments.length; _i++) {
a[_i] = arguments[_i];
}
return from(f.apply(void 0, a));
}; };
}
exports.fromNullableK = fromNullableK;
/**
* @category combinators
* @since 2.9.0
*/
function chainNullableK(e) {
var from = fromNullableK(e);
return function (f) { return exports.chain(from(f)); };
}
exports.chainNullableK = chainNullableK;
/**
* Returns a `Right` if is a `Left` (and vice versa).
*
* @category combinators
* @since 2.0.0
*/
function swap(ma) {
return exports.isLeft(ma) ? exports.right(ma.left) : exports.left(ma.right);
}
exports.swap = swap;
/**
* Useful for recovering from errors.
*
* @category combinators
* @since 2.0.0
*/
function orElse(onLeft) {
return function (ma) { return (exports.isLeft(ma) ? onLeft(ma.left) : ma); };
}
exports.orElse = orElse;
/**
* Less strict version of [`filterOrElse`](#filterOrElse).
*
* @since 2.9.0
*/
var filterOrElseW = function (predicate, onFalse) {
return exports.chainW(function (a) { return (predicate(a) ? exports.right(a) : exports.left(onFalse(a))); });
};
exports.filterOrElseW = filterOrElseW;
/**
* Derivable from `MonadThrow`.
*
* @example
* import { filterOrElse, left, right } from 'fp-ts/Either'
* import { pipe } from 'fp-ts/function'
*
* assert.deepStrictEqual(
* pipe(
* right(1),
* filterOrElse(
* (n) => n > 0,
* () => 'error'
* )
* ),
* right(1)
* )
* assert.deepStrictEqual(
* pipe(
* right(-1),
* filterOrElse(
* (n) => n > 0,
* () => 'error'
* )
* ),
* left('error')
* )
* assert.deepStrictEqual(
* pipe(
* left('a'),
* filterOrElse(
* (n) => n > 0,
* () => 'error'
* )
* ),
* left('a')
* )
*
* @category combinators
* @since 2.0.0
*/
exports.filterOrElse = exports.filterOrElseW;
// -------------------------------------------------------------------------------------
// non-pipeables
// -------------------------------------------------------------------------------------
var map_ = function (fa, f) { return function_1.pipe(fa, exports.map(f)); };
var ap_ = function (fab, fa) { return function_1.pipe(fab, exports.ap(fa)); };
/* istanbul ignore next */
var chain_ = function (ma, f) { return function_1.pipe(ma, exports.chain(f)); };
/* istanbul ignore next */
var reduce_ = function (fa, b, f) { return function_1.pipe(fa, exports.reduce(b, f)); };
/* istanbul ignore next */
var foldMap_ = function (M) { return function (fa, f) {
var foldMapM = exports.foldMap(M);
return function_1.pipe(fa, foldMapM(f));
}; };
/* istanbul ignore next */
var reduceRight_ = function (fa, b, f) { return function_1.pipe(fa, exports.reduceRight(b, f)); };
var traverse_ = function (F) {
var traverseF = exports.traverse(F);
return function (ta, f) { return function_1.pipe(ta, traverseF(f)); };
};
var bimap_ = function (fa, f, g) { return function_1.pipe(fa, exports.bimap(f, g)); };
var mapLeft_ = function (fa, f) { return function_1.pipe(fa, exports.mapLeft(f)); };
/* istanbul ignore next */
var alt_ = function (fa, that) { return function_1.pipe(fa, exports.alt(that)); };
/* istanbul ignore next */
var extend_ = function (wa, f) { return function_1.pipe(wa, exports.extend(f)); };
var chainRec_ = function (a, f) {
return ChainRec_1.tailRec(f(a), function (e) {
return exports.isLeft(e) ? exports.right(exports.left(e.left)) : exports.isLeft(e.right) ? exports.left(f(e.right.left)) : exports.right(exports.right(e.right.right));
});
};
// -------------------------------------------------------------------------------------
// pipeables
// -------------------------------------------------------------------------------------
/**
* `map` can be used to turn functions `(a: A) => B` into functions `(fa: F<A>) => F<B>` whose argument and return types
* use the type constructor `F` to represent some computational context.
*
* @category Functor
* @since 2.0.0
*/
var map = function (f) { return function (fa) {
return exports.isLeft(fa) ? fa : exports.right(f(fa.right));
}; };
exports.map = map;
/**
* Map a pair of functions over the two type arguments of the bifunctor.
*
* @category Bifunctor
* @since 2.0.0
*/
var bimap = function (f, g) { return function (fa) { return (exports.isLeft(fa) ? exports.left(f(fa.left)) : exports.right(g(fa.right))); }; };
exports.bimap = bimap;
/**
* Map a function over the first type argument of a bifunctor.
*
* @category Bifunctor
* @since 2.0.0
*/
var mapLeft = function (f) { return function (fa) {
return exports.isLeft(fa) ? exports.left(f(fa.left)) : fa;
}; };
exports.mapLeft = mapLeft;
/**
* Less strict version of [`ap`](#ap).
*
* @category Apply
* @since 2.8.0
*/
var apW = function (fa) { return function (fab) {
return exports.isLeft(fab) ? fab : exports.isLeft(fa) ? fa : exports.right(fab.right(fa.right));
}; };
exports.apW = apW;
/**
* Apply a function to an argument under a type constructor.
*
* @category Apply
* @since 2.0.0
*/
exports.ap = exports.apW;
/**
* Combine two effectful actions, keeping only the result of the first.
*
* Derivable from `Apply`.
*
* @category combinators
* @since 2.0.0
*/
var apFirst = function (fb) {
return function_1.flow(exports.map(function (a) { return function () { return a; }; }), exports.ap(fb));
};
exports.apFirst = apFirst;
/**
* Combine two effectful actions, keeping only the result of the second.
*
* Derivable from `Apply`.
*
* @category combinators
* @since 2.0.0
*/
var apSecond = function (fb) {
return function_1.flow(exports.map(function () { return function (b) { return b; }; }), exports.ap(fb));
};
exports.apSecond = apSecond;
/**
* Wrap a value into the type constructor.
*
* Equivalent to [`right`](#right).
*
* @example
* import * as E from 'fp-ts/Either'
*
* assert.deepStrictEqual(E.of('a'), E.right('a'))
*
* @category Applicative
* @since 2.7.0
*/
exports.of = exports.right;
/**
* Less strict version of [`chain`](#chain).
*
* @category Monad
* @since 2.6.0
*/
var chainW = function (f) { return function (ma) {
return exports.isLeft(ma) ? ma : f(ma.right);
}; };
exports.chainW = chainW;
/**
* Composes computations in sequence, using the return value of one computation to determine the next computation.
*
* @category Monad
* @since 2.0.0
*/
exports.chain = exports.chainW;
/**
* Less strict version of [`chainFirst`](#chainFirst)
*
* Derivable from `Monad`.
*
* @category combinators
* @since 2.8.0
*/
var chainFirstW = function (f) { return function (ma) {
return function_1.pipe(ma, exports.chainW(function (a) {
return function_1.pipe(f(a), exports.map(function () { return a; }));
}));
}; };
exports.chainFirstW = chainFirstW;
/**
* Composes computations in sequence, using the return value of one computation to determine the next computation and
* keeping only the result of the first.
*
* Derivable from `Monad`.
*
* @category combinators
* @since 2.0.0
*/
exports.chainFirst = exports.chainFirstW;
/**
* The `flatten` function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level.
*
* Derivable from `Monad`.
*
* @example
* import * as E from 'fp-ts/Either'
*
* assert.deepStrictEqual(E.flatten(E.right(E.right('a'))), E.right('a'))
* assert.deepStrictEqual(E.flatten(E.right(E.left('e'))), E.left('e'))
* assert.deepStrictEqual(E.flatten(E.left('e')), E.left('e'))
*
* @category combinators
* @since 2.0.0
*/
exports.flatten =
/*#__PURE__*/
exports.chain(function_1.identity);
/**
* Less strict version of [`alt`](#alt).
*
* @category Alt
* @since 2.9.0
*/
var altW = function (that) { return function (fa) { return (exports.isLeft(fa) ? that() : fa); }; };
exports.altW = altW;
/**
* Identifies an associative operation on a type constructor. It is similar to `Semigroup`, except that it applies to
* types of kind `* -> *`.
*
* @category Alt
* @since 2.0.0
*/
exports.alt = exports.altW;
/**
* @category Extend
* @since 2.0.0
*/
var extend = function (f) { return function (wa) {
return exports.isLeft(wa) ? wa : exports.right(f(wa));
}; };
exports.extend = extend;
/**
* Derivable from `Extend`.
*
* @category combinators
* @since 2.0.0
*/
exports.duplicate =
/*#__PURE__*/
exports.extend(function_1.identity);
/**
* Left-associative fold of a structure.
*
* @example
* import { pipe } from 'fp-ts/function'
* import * as E from 'fp-ts/Either'
*
* const startWith = 'prefix'
* const concat = (a: string, b: string) => `${a}:${b}`
*
* assert.deepStrictEqual(
* pipe(E.right('a'), E.reduce(startWith, concat)),
* 'prefix:a',
* )
*
* assert.deepStrictEqual(
* pipe(E.left('e'), E.reduce(startWith, concat)),
* 'prefix',
* )
*
* @category Foldable
* @since 2.0.0
*/
var reduce = function (b, f) { return function (fa) {
return exports.isLeft(fa) ? b : f(b, fa.right);
}; };
exports.reduce = reduce;
/**
* Map each element of the structure to a monoid, and combine the results.
*
* @example
* import { pipe } from 'fp-ts/function';
* import * as E from 'fp-ts/Either'
* import { monoidString } from 'fp-ts/Monoid'
*
* const yell = (a: string) => `${a}!`
*
* assert.deepStrictEqual(
* pipe(E.right('a'), E.foldMap(monoidString)(yell)),
* 'a!',
* )
*
* assert.deepStrictEqual(
* pipe(E.left('e'), E.foldMap(monoidString)(yell)),
* monoidString.empty,
* )
*
* @category Foldable
* @since 2.0.0
*/
var foldMap = function (M) { return function (f) { return function (fa) {
return exports.isLeft(fa) ? M.empty : f(fa.right);
}; }; };
exports.foldMap = foldMap;
/**
* Right-associative fold of a structure.
*
* @example
* import { pipe } from 'fp-ts/function'
* import * as E from 'fp-ts/Either'
*
* const startWith = 'postfix'
* const concat = (a: string, b: string) => `${a}:${b}`
*
* assert.deepStrictEqual(
* pipe(E.right('a'), E.reduceRight(startWith, concat)),
* 'a:postfix',
* )
*
* assert.deepStrictEqual(
* pipe(E.left('e'), E.reduceRight(startWith, concat)),
* 'postfix',
* )
*
* @category Foldable
* @since 2.0.0
*/
var reduceRight = function (b, f) { return function (fa) {
return exports.isLeft(fa) ? b : f(fa.right, b);
}; };
exports.reduceRight = reduceRight;
/**
* Map each element of a structure to an action, evaluate these actions from left to right, and collect the results.
*
* @example
* import { pipe } from 'fp-ts/function'
* import * as A from 'fp-ts/Array'
* import * as E from 'fp-ts/Either'
* import * as O from 'fp-ts/Option'
*
* assert.deepStrictEqual(
* pipe(E.right(['a']), E.traverse(O.option)(A.head)),
* O.some(E.right('a')),
* )
*
* assert.deepStrictEqual(
* pipe(E.right([]), E.traverse(O.option)(A.head)),
* O.none,
* )
*
* @category Traversable
* @since 2.6.3
*/
var traverse = function (F) { return function (f) { return function (ta) { return (exports.isLeft(ta) ? F.of(exports.left(ta.left)) : F.map(f(ta.right), exports.right)); }; }; };
exports.traverse = traverse;
/**
* Evaluate each monadic action in the structure from left to right, and collect the results.
*
* @example
* import { pipe } from 'fp-ts/function'
* import * as E from 'fp-ts/Either'
* import * as O from 'fp-ts/Option'
*
* assert.deepStrictEqual(
* pipe(E.right(O.some('a')), E.sequence(O.option)),
* O.some(E.right('a')),
* )
*
* assert.deepStrictEqual(
* pipe(E.right(O.none), E.sequence(O.option)),
* O.none
* )
*
* @category Traversable
* @since 2.6.3
*/
var sequence = function (F) { return function (ma) {
return exports.isLeft(ma) ? F.of(exports.left(ma.left)) : F.map(ma.right, exports.right);
}; };
exports.sequence = sequence;
/**
* @category MonadThrow
* @since 2.6.3
*/
exports.throwError = exports.left;
// -------------------------------------------------------------------------------------
// instances
// -------------------------------------------------------------------------------------
/**
* @category instances
* @since 2.0.0
*/
exports.URI = 'Either';
/**
* @category instances
* @since 2.0.0
*/
function getShow(SE, SA) {
return {
show: function (ma) { return (exports.isLeft(ma) ? "left(" + SE.show(ma.left) + ")" : "right(" + SA.show(ma.right) + ")"); }
};
}
exports.getShow = getShow;
/**
* @category instances
* @since 2.0.0
*/
function getEq(EL, EA) {
return {
equals: function (x, y) {
return x === y || (exports.isLeft(x) ? exports.isLeft(y) && EL.equals(x.left, y.left) : exports.isRight(y) && EA.equals(x.right, y.right));
}
};
}
exports.getEq = getEq;
/**
* Semigroup returning the left-most non-`Left` value. If both operands are `Right`s then the inner values are
* concatenated using the provided `Semigroup`
*
* @example
* import { getSemigroup, left, right } from 'fp-ts/Either'
* import { semigroupSum } from 'fp-ts/Semigroup'
*
* const S = getSemigroup<string, number>(semigroupSum)
* assert.deepStrictEqual(S.concat(left('a'), left('b')), left('a'))
* assert.deepStrictEqual(S.concat(left('a'), right(2)), right(2))
* assert.deepStrictEqual(S.concat(right(1), left('b')), right(1))
* assert.deepStrictEqual(S.concat(right(1), right(2)), right(3))
*
* @category instances
* @since 2.0.0
*/
function getSemigroup(S) {
return {
concat: function (x, y) { return (exports.isLeft(y) ? x : exports.isLeft(x) ? y : exports.right(S.concat(x.right, y.right))); }
};
}
exports.getSemigroup = getSemigroup;
/**
* Semigroup returning the left-most `Left` value. If both operands are `Right`s then the inner values
* are concatenated using the provided `Semigroup`
*
* @example
* import { getApplySemigroup, left, right } from 'fp-ts/Either'
* import { semigroupSum } from 'fp-ts/Semigroup'
*
* const S = getApplySemigroup<string, number>(semigroupSum)
* assert.deepStrictEqual(S.concat(left('a'), left('b')), left('a'))
* assert.deepStrictEqual(S.concat(left('a'), right(2)), left('a'))
* assert.deepStrictEqual(S.concat(right(1), left('b')), left('b'))
* assert.deepStrictEqual(S.concat(right(1), right(2)), right(3))
*
* @category instances
* @since 2.0.0
*/
function getApplySemigroup(S) {
return {
concat: function (x, y) { return (exports.isLeft(x) ? x : exports.isLeft(y) ? y : exports.right(S.concat(x.right, y.right))); }
};
}
exports.getApplySemigroup = getApplySemigroup;
/**
* @category instances
* @since 2.0.0
*/
function getApplyMonoid(M) {
return {
concat: getApplySemigroup(M).concat,
empty: exports.right(M.empty)
};
}
exports.getApplyMonoid = getApplyMonoid;
/**
* Builds a `Filterable` instance for `Either` given `Monoid` for the left side
*
* @category instances
* @since 3.0.0
*/
function getFilterable(M) {
var empty = exports.left(M.empty);
var compact = function (ma) {
return exports.isLeft(ma) ? ma : ma.right._tag === 'None' ? empty : exports.right(ma.right.value);
};
var separate = function (ma) {
return exports.isLeft(ma)
? { left: ma, right: ma }
: exports.isLeft(ma.right)
? { left: exports.right(ma.right.left), right: empty }
: { left: empty, right: exports.right(ma.right.right) };
};
var partitionMap = function (ma, f) {
if (exports.isLeft(ma)) {
return { left: ma, right: ma };
}
var e = f(ma.right);
return exports.isLeft(e) ? { left: exports.right(e.left), right: empty } : { left: empty, right: exports.right(e.right) };
};
var partition = function (ma, p) {
return exports.isLeft(ma)
? { left: ma, right: ma }
: p(ma.right)
? { left: empty, right: exports.right(ma.right) }
: { left: exports.right(ma.right), right: empty };
};
var filterMap = function (ma, f) {
if (exports.isLeft(ma)) {
return ma;
}
var ob = f(ma.right);
return ob._tag === 'None' ? empty : exports.right(ob.value);
};
var filter = function (ma, predicate) {
return exports.isLeft(ma) ? ma : predicate(ma.right) ? ma : empty;
};
return {
URI: exports.URI,
_E: undefined,
map: map_,
compact: compact,
separate: separate,
filter: filter,
filterMap: filterMap,
partition: partition,
partitionMap: partitionMap
};
}
exports.getFilterable = getFilterable;
/**
* Builds `Witherable` instance for `Either` given `Monoid` for the left side
*
* @category instances
* @since 2.0.0
*/
function getWitherable(M) {
var F_ = getFilterable(M);
var wither = function (F) {
var traverseF = traverse_(F);
return function (ma, f) { return F.map(traverseF(ma, f), F_.compact); };
};
var wilt = function (F) {
var traverseF = traverse_(F);
return function (ma, f) { return F.map(traverseF(ma, f), F_.separate); };
};
return {
URI: exports.URI,
_E: undefined,
map: map_,
compact: F_.compact,
separate: F_.separate,
filter: F_.filter,
filterMap: F_.filterMap,
partition: F_.partition,
partitionMap: F_.partitionMap,
traverse: traverse_,
sequence: exports.sequence,
reduce: reduce_,
foldMap: foldMap_,
reduceRight: reduceRight_,
wither: wither,
wilt: wilt
};
}
exports.getWitherable = getWitherable;
/**
* @category instances
* @since 2.7.0
*/
function getApplicativeValidation(SE) {
return {
URI: exports.URI,
_E: undefined,
map: map_,
ap: function (fab, fa) {
return exports.isLeft(fab)
? exports.isLeft(fa)
? exports.left(SE.concat(fab.left, fa.left))
: fab
: exports.isLeft(fa)
? fa
: exports.right(fab.right(fa.right));
},
of: exports.of
};
}
exports.getApplicativeValidation = getApplicativeValidation;
/**
* @category instances
* @since 2.7.0
*/
function getAltValidation(SE) {
return {
URI: exports.URI,
_E: undefined,
map: map_,
alt: function (me, that) {
if (exports.isRight(me)) {
return me;
}
var ea = that();
return exports.isLeft(ea) ? exports.left(SE.concat(me.left, ea.left)) : ea;
}
};
}
exports.getAltValidation = getAltValidation;
// TODO: remove in v3
/**
* @category instances
* @since 2.0.0
*/
function getValidation(SE) {
var applicativeValidation = getApplicativeValidation(SE);
var altValidation = getAltValidation(SE);
return {
URI: exports.URI,
_E: undefined,
map: map_,
of: exports.of,
chain: chain_,
bimap: bimap_,
mapLeft: mapLeft_,
reduce: reduce_,
foldMap: foldMap_,
reduceRight: reduceRight_,
extend: extend_,
traverse: traverse_,
sequence: exports.sequence,
chainRec: chainRec_,
throwError: exports.throwError,
ap: applicativeValidation.ap,
alt: altValidation.alt
};
}
exports.getValidation = getValidation;
/**
* @category instances
* @since 2.0.0
*/
function getValidationSemigroup(SE, SA) {
return {
concat: function (x, y) {
return exports.isLeft(x) ? (exports.isLeft(y) ? exports.left(SE.concat(x.left, y.left)) : x) : exports.isLeft(y) ? y : exports.right(SA.concat(x.right, y.right));
}
};
}
exports.getValidationSemigroup = getValidationSemigroup;
/**
* @category instances
* @since 2.7.0
*/
exports.Functor = {
URI: exports.URI,
map: map_
};
/**
* @category instances
* @since 2.7.0
*/
exports.Applicative = {
URI: exports.URI,
map: map_,
ap: ap_,
of: exports.of
};
/**
* @category instances
* @since 2.7.0
*/
exports.Monad = {
URI: exports.URI,
map: map_,
ap: ap_,
of: exports.of,
chain: chain_
};
/**
* @category instances
* @since 2.7.0
*/
exports.Foldable = {
URI: exports.URI,
reduce: reduce_,
foldMap: foldMap_,
reduceRight: reduceRight_
};
/**
* @category instances
* @since 2.7.0
*/
exports.Traversable = {
URI: exports.URI,
map: map_,
reduce: reduce_,
foldMap: foldMap_,
reduceRight: reduceRight_,
traverse: traverse_,
sequence: exports.sequence
};
/**
* @category instances
* @since 2.7.0
*/
exports.Bifunctor = {
URI: exports.URI,
bimap: bimap_,
mapLeft: mapLeft_
};
/**
* @category instances
* @since 2.7.0
*/
exports.Alt = {
URI: exports.URI,
map: map_,
alt: alt_
};
/**
* @category instances
* @since 2.7.0
*/
exports.Extend = {
URI: exports.URI,
map: map_,
extend: extend_
};
/**
* @category instances
* @since 2.7.0
*/
exports.ChainRec = {
URI: exports.URI,
map: map_,
ap: ap_,
chain: chain_,
chainRec: chainRec_
};
/**
* @category instances
* @since 2.7.0
*/
exports.MonadThrow = {
URI: exports.URI,
map: map_,
ap: ap_,
of: exports.of,
chain: chain_,
throwError: exports.throwError
};
/**
* @category instances
* @since 2.0.0
*/
function getValidationMonoid(SE, SA) {
return {
concat: getValidationSemigroup(SE, SA).concat,
empty: exports.right(SA.empty)
};
}
exports.getValidationMonoid = getValidationMonoid;
/**
* @category instances
* @since 2.0.0
*/
exports.either = {
URI: exports.URI,
map: map_,
of: exports.of,
ap: ap_,
chain: chain_,
reduce: reduce_,
foldMap: foldMap_,
reduceRight: reduceRight_,
traverse: traverse_,
sequence: exports.sequence,
bimap: bimap_,
mapLeft: mapLeft_,
alt: alt_,
extend: extend_,
chainRec: chainRec_,
throwError: exports.throwError
};
// -------------------------------------------------------------------------------------
// utils
// -------------------------------------------------------------------------------------
/**
* Default value for the `onError` argument of `tryCatch`
*
* @since 2.0.0
*/
function toError(e) {
return e instanceof Error ? e : new Error(String(e));
}
exports.toError = toError;
/**
* @since 2.0.0
*/
function elem(E) {
return function (a, ma) { return (exports.isLeft(ma) ? false : E.equals(a, ma.right)); };
}
exports.elem = elem;
/**
* Returns `false` if `Left` or returns the result of the application of the given predicate to the `Right` value.
*
* @example
* import { exists, left, right } from 'fp-ts/Either'
*
* const gt2 = exists((n: number) => n > 2)
*
* assert.strictEqual(gt2(left('a')), false)
* assert.strictEqual(gt2(right(1)), false)
* assert.strictEqual(gt2(right(3)), true)
*
* @since 2.0.0
*/
function exists(predicate) {
return function (ma) { return (exports.isLeft(ma) ? false : predicate(ma.right)); };
}
exports.exists = exists;
// -------------------------------------------------------------------------------------
// do notation
// -------------------------------------------------------------------------------------
/**
* @since 2.9.0
*/
exports.Do =
/*#__PURE__*/
exports.of({});
/**
* @since 2.8.0
*/
var bindTo = function (name) {
return exports.map(function_1.bindTo_(name));
};
exports.bindTo = bindTo;
/**
* @since 2.8.0
*/
var bindW = function (name, f) {
return exports.chainW(function (a) {
return function_1.pipe(f(a), exports.map(function (b) { return function_1.bind_(a, name, b); }));
});
};
exports.bindW = bindW;
/**
* @since 2.8.0
*/
exports.bind = exports.bindW;
// -------------------------------------------------------------------------------------
// pipeable sequence S
// -------------------------------------------------------------------------------------
/**
* @since 2.8.0
*/
var apSW = function (name, fb) {
return function_1.flow(exports.map(function (a) { return function (b) { return function_1.bind_(a, name, b); }; }), exports.apW(fb));
};
exports.apSW = apSW;
/**
* @since 2.8.0
*/
exports.apS = exports.apSW;
// -------------------------------------------------------------------------------------
// array utils
// -------------------------------------------------------------------------------------
/**
*
* @since 2.9.0
*/
var traverseArrayWithIndex = function (f) { return function (arr) {
// tslint:disable-next-line: readonly-array
var result = [];
for (var i = 0; i < arr.length; i++) {
var e = f(i, arr[i]);
if (e._tag === 'Left') {
return e;
}
result.push(e.right);
}
return exports.right(result);
}; };
exports.traverseArrayWithIndex = traverseArrayWithIndex;
/**
* map an array using provided function to Either then transform to Either of the array
* this function has the same behavior of `A.traverse(E.either)` but it's optimized and performs better
*
* @example
*
*
* import { traverseArray, left, right, fromPredicate } from 'fp-ts/Either'
* import { pipe } from 'fp-ts/function'
* import * as A from 'fp-ts/Array'
*
* const arr = A.range(0, 10)
* assert.deepStrictEqual(
* pipe(
* arr,
* traverseArray((x) => right(x))
* ),
* right(arr)
* )
* assert.deepStrictEqual(
* pipe(
* arr,
* traverseArray(
* fromPredicate(
* (x) => x > 5,
* () => 'a'
* )
* )
* ),
* left('a')
* )
* @since 2.9.0
*/
var traverseArray = function (f) { return exports.traverseArrayWithIndex(function (_, a) { return f(a); }); };
exports.traverseArray = traverseArray;
/**
* convert an array of either to an either of array
* this function has the same behavior of `A.sequence(E.either)` but it's optimized and performs better
*
* @example
*
* import { sequenceArray, left, right } from 'fp-ts/Either'
* import { pipe } from 'fp-ts/function'
* import * as A from 'fp-ts/Array'
*
* const arr = A.range(0, 10)
* assert.deepStrictEqual(pipe(arr, A.map(right), sequenceArray), right(arr))
* assert.deepStrictEqual(pipe(arr, A.map(right), A.cons(left('Error')), sequenceArray), left('Error'))
*
* @since 2.9.0
*/
exports.sequenceArray =
/*#__PURE__*/
exports.traverseArray(function_1.identity);