UNPKG

fp-ts

Version:

Functional programming in TypeScript

1,276 lines (1,275 loc) 35.9 kB
"use strict"; 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);