Either overview
Added in v2.0.0
Table of contents
- combining
- constructors
- do notation
- equivalence
- error handling
- filtering & conditionals
- generators
- getters
- guards
- mapping
- models
- pattern matching
- sequencing
- symbols
- type lambdas
- utils
- zipping
combining
all
Takes a structure of Either
s and returns an Either
of values with the same structure.
- If a tuple is supplied, then the returned
Either
will contain a tuple with the same length. - If a struct is supplied, then the returned
Either
will contain a struct with the same keys. - If an iterable is supplied, then the returned
Either
will contain an array.
Signature
export declare const all: <const I extends Iterable<Either<any, any>> | Record<string, Either<any, any>>>(
input: I
) => [I] extends [readonly Either<any, any>[]]
? Either<
{ -readonly [K in keyof I]: [I[K]] extends [Either<infer R, any>] ? R : never },
I[number] extends never ? never : [I[number]] extends [Either<any, infer L>] ? L : never
>
: [I] extends [Iterable<Either<infer R, infer L>>]
? Either<R[], L>
: Either<
{ -readonly [K in keyof I]: [I[K]] extends [Either<infer R, any>] ? R : never },
I[keyof I] extends never ? never : [I[keyof I]] extends [Either<any, infer L>] ? L : never
>
Example
import * as Either from "effect/Either"
assert.deepStrictEqual(Either.all([Either.right(1), Either.right(2)]), Either.right([1, 2]))
assert.deepStrictEqual(
Either.all({ right: Either.right(1), b: Either.right("hello") }),
Either.right({ right: 1, b: "hello" })
)
assert.deepStrictEqual(Either.all({ right: Either.right(1), b: Either.left("error") }), Either.left("error"))
Added in v2.0.0
ap
Signature
export declare const ap: {
<R, L2>(that: Either<R, L2>): <R2, L>(self: Either<(right: R) => R2, L>) => Either<R2, L2 | L>
<R, R2, L, L2>(self: Either<(right: R) => R2, L>, that: Either<R, L2>): Either<R2, L | L2>
}
Added in v2.0.0
constructors
fromNullable
Takes a lazy default and a nullable value, if the value is not nully (null
or undefined
), turn it into a Right
, if the value is nully use the provided default as a Left
.
Signature
export declare const fromNullable: {
<R, L>(onNullable: (right: R) => L): (self: R) => Either<NonNullable<R>, L>
<R, L>(self: R, onNullable: (right: R) => L): Either<NonNullable<R>, L>
}
Example
import * as Either from "effect/Either"
assert.deepStrictEqual(
Either.fromNullable(1, () => "fallback"),
Either.right(1)
)
assert.deepStrictEqual(
Either.fromNullable(null, () => "fallback"),
Either.left("fallback")
)
Added in v2.0.0
fromOption
Signature
export declare const fromOption: {
<L>(onNone: () => L): <R>(self: Option<R>) => Either<R, L>
<R, L>(self: Option<R>, onNone: () => L): Either<R, L>
}
Example
import * as Either from "effect/Either"
import * as Option from "effect/Option"
assert.deepStrictEqual(
Either.fromOption(Option.some(1), () => "error"),
Either.right(1)
)
assert.deepStrictEqual(
Either.fromOption(Option.none(), () => "error"),
Either.left("error")
)
Added in v2.0.0
left
Constructs a new Either
holding a Left
value. This usually represents a failure, due to the right-bias of this structure.
Signature
export declare const left: <L>(left: L) => Either<never, L>
Added in v2.0.0
right
Constructs a new Either
holding a Right
value. This usually represents a successful value due to the right bias of this structure.
Signature
export declare const right: <R>(right: R) => Either<R, never>
Added in v2.0.0
try
Imports a synchronous side-effect into a pure Either
value, translating any thrown exceptions into typed failed eithers creating with Either.left
.
Signature
export declare const try: { <R, L>(options: { readonly try: LazyArg<R>; readonly catch: (error: unknown) => L; }): Either<R, L>; <R>(evaluate: LazyArg<R>): Either<R, unknown>; }
Added in v2.0.0
do notation
Do
Signature
export declare const Do: Either<{}, never>
Added in v2.4.0
bind
Binds an effectful value in a do
scope
Signature
export declare const bind: {
<N extends string, K, A, E2>(
tag: Exclude<N, keyof K>,
f: (_: K) => Either<A, E2>
): <E>(self: Either<K, E>) => Either<MergeRecord<K, { [k in N]: A }>, E2 | E>
<K, E, N extends string, A, E2>(
self: Either<E, K>,
tag: Exclude<N, keyof K>,
f: (_: K) => Either<A, E2>
): Either<MergeRecord<K, { [k in N]: A }>, E | E2>
}
Added in v2.4.0
bindTo
Signature
export declare const bindTo: {
<N extends string>(tag: N): <A, E>(self: Either<A, E>) => Either<Record<N, A>, E>
<A, E, N extends string>(self: Either<A, E>, tag: N): Either<Record<N, A>, E>
}
Added in v2.4.0
let
Like bind for values
Signature
export declare const let: {
<N extends string, K, A>(
tag: Exclude<N, keyof K>,
f: (_: K) => A
): <E>(self: Either<K, E>) => Either<MergeRecord<K, { [k in N]: A }>, E>
<K, E, N extends string, A>(
self: Either<K, E>,
tag: Exclude<N, keyof K>,
f: (_: K) => A
): Either<MergeRecord<K, { [k in N]: A }>, E>
}
Added in v2.4.0
equivalence
getEquivalence
Signature
export declare const getEquivalence: <R, L>({
left,
right
}: {
right: Equivalence.Equivalence<R>
left: Equivalence.Equivalence<L>
}) => Equivalence.Equivalence<Either<R, L>>
Added in v2.0.0
error handling
orElse
Returns self
if it is a Right
or that
otherwise.
Signature
export declare const orElse: {
<L, R2, L2>(that: (left: L) => Either<R2, L2>): <R>(self: Either<R, L>) => Either<R2 | R, L2>
<R, L, R2, L2>(self: Either<R, L>, that: (left: L) => Either<R2, L2>): Either<R | R2, L2>
}
Added in v2.0.0
filtering & conditionals
filterOrLeft
Filter the right value with the provided function. If the predicate fails, set the left value with the result of the provided function.
Signature
export declare const filterOrLeft: {
<R, B extends R, L2>(
refinement: Refinement<NoInfer<R>, B>,
orLeftWith: (right: NoInfer<R>) => L2
): <L>(self: Either<R, L>) => Either<B, L2 | L>
<R, L2>(
predicate: Predicate<NoInfer<R>>,
orLeftWith: (right: NoInfer<R>) => L2
): <L>(self: Either<R, L>) => Either<R, L2 | L>
<R, L, B extends R, L2>(
self: Either<R, L>,
refinement: Refinement<R, B>,
orLeftWith: (right: R) => L2
): Either<B, L | L2>
<R, L, E2>(self: Either<R, L>, predicate: Predicate<R>, orLeftWith: (right: R) => E2): Either<R, L | E2>
}
Example
import * as E from "effect/Either"
import { pipe } from "effect/Function"
const isPositive = (n: number): boolean => n > 0
assert.deepStrictEqual(
pipe(
E.right(1),
E.filterOrLeft(isPositive, (n) => `${n} is not positive`)
),
E.right(1)
)
assert.deepStrictEqual(
pipe(
E.right(0),
E.filterOrLeft(isPositive, (n) => `${n} is not positive`)
),
E.left("0 is not positive")
)
Added in v2.0.0
generators
gen
Signature
export declare const gen: Gen.Gen<EitherTypeLambda, Gen.Adapter<EitherTypeLambda>>
Added in v2.0.0
getters
getLeft
Converts a Either
to an Option
discarding the value.
Signature
export declare const getLeft: <R, L>(self: Either<R, L>) => Option<L>
Example
import * as O from "effect/Option"
import * as E from "effect/Either"
assert.deepStrictEqual(E.getLeft(E.right("ok")), O.none())
assert.deepStrictEqual(E.getLeft(E.left("err")), O.some("err"))
Added in v2.0.0
getOrElse
Returns the wrapped value if it’s a Right
or a default value if is a Left
.
Signature
export declare const getOrElse: {
<L, R2>(onLeft: (left: L) => R2): <R>(self: Either<R, L>) => R2 | R
<R, L, R2>(self: Either<R, L>, onLeft: (left: L) => R2): R | R2
}
Example
import * as Either from "effect/Either"
assert.deepStrictEqual(
Either.getOrElse(Either.right(1), (error) => error + "!"),
1
)
assert.deepStrictEqual(
Either.getOrElse(Either.left("not a number"), (error) => error + "!"),
"not a number!"
)
Added in v2.0.0
getOrNull
Signature
export declare const getOrNull: <R, L>(self: Either<R, L>) => R | null
Example
import * as Either from "effect/Either"
assert.deepStrictEqual(Either.getOrNull(Either.right(1)), 1)
assert.deepStrictEqual(Either.getOrNull(Either.left("a")), null)
Added in v2.0.0
getOrThrow
Extracts the value of an Either
or throws if the Either
is Left
.
The thrown error is a default error. To configure the error thrown, see {@link getOrThrowWith}.
Signature
export declare const getOrThrow: <R, L>(self: Either<R, L>) => R
Example
import * as E from "effect/Either"
assert.deepStrictEqual(E.getOrThrow(E.right(1)), 1)
assert.throws(() => E.getOrThrow(E.left("error")))
Added in v2.0.0
getOrThrowWith
Extracts the value of an Either
or throws if the Either
is Left
.
If a default error is sufficient for your use case and you don’t need to configure the thrown error, see {@link getOrThrow}.
Signature
export declare const getOrThrowWith: {
<L>(onLeft: (left: L) => unknown): <A>(self: Either<A, L>) => A
<R, L>(self: Either<R, L>, onLeft: (left: L) => unknown): R
}
Example
import * as E from "effect/Either"
assert.deepStrictEqual(
E.getOrThrowWith(E.right(1), () => new Error("Unexpected Left")),
1
)
assert.throws(() => E.getOrThrowWith(E.left("error"), () => new Error("Unexpected Left")))
Added in v2.0.0
getOrUndefined
Signature
export declare const getOrUndefined: <R, L>(self: Either<R, L>) => R | undefined
Example
import * as Either from "effect/Either"
assert.deepStrictEqual(Either.getOrUndefined(Either.right(1)), 1)
assert.deepStrictEqual(Either.getOrUndefined(Either.left("a")), undefined)
Added in v2.0.0
getRight
Converts a Either
to an Option
discarding the Left
.
Alias of {@link toOption}.
Signature
export declare const getRight: <R, L>(self: Either<R, L>) => Option<R>
Example
import * as O from "effect/Option"
import * as E from "effect/Either"
assert.deepStrictEqual(E.getRight(E.right("ok")), O.some("ok"))
assert.deepStrictEqual(E.getRight(E.left("err")), O.none())
Added in v2.0.0
merge
Signature
export declare const merge: <R, L>(self: Either<R, L>) => R | L
Added in v2.0.0
guards
isEither
Tests if a value is a Either
.
Signature
export declare const isEither: (input: unknown) => input is Either<unknown, unknown>
Example
import { isEither, left, right } from "effect/Either"
assert.deepStrictEqual(isEither(right(1)), true)
assert.deepStrictEqual(isEither(left("a")), true)
assert.deepStrictEqual(isEither({ right: 1 }), false)
Added in v2.0.0
isLeft
Determine if a Either
is a Left
.
Signature
export declare const isLeft: <R, L>(self: Either<R, L>) => self is Left<L, R>
Example
import { isLeft, left, right } from "effect/Either"
assert.deepStrictEqual(isLeft(right(1)), false)
assert.deepStrictEqual(isLeft(left("a")), true)
Added in v2.0.0
isRight
Determine if a Either
is a Right
.
Signature
export declare const isRight: <R, L>(self: Either<R, L>) => self is Right<L, R>
Example
import { isRight, left, right } from "effect/Either"
assert.deepStrictEqual(isRight(right(1)), true)
assert.deepStrictEqual(isRight(left("a")), false)
Added in v2.0.0
mapping
flip
Returns an Either
that swaps the error/success cases. This allows you to use all methods on the error channel, possibly before flipping back.
Signature
export declare const flip: <R, L>(self: Either<R, L>) => Either<L, R>
Added in v2.0.0
map
Maps the Right
side of an Either
value to a new Either
value.
Signature
export declare const map: {
<R, R2>(f: (right: R) => R2): <L>(self: Either<R, L>) => Either<R2, L>
<R, L, R2>(self: Either<R, L>, f: (right: R) => R2): Either<R2, L>
}
Added in v2.0.0
mapBoth
Signature
export declare const mapBoth: {
<L, L2, R, R2>(options: {
readonly onLeft: (left: L) => L2
readonly onRight: (right: R) => R2
}): (self: Either<R, L>) => Either<R2, L2>
<L, R, L2, R2>(
self: Either<R, L>,
options: { readonly onLeft: (left: L) => L2; readonly onRight: (right: R) => R2 }
): Either<R2, L2>
}
Added in v2.0.0
mapLeft
Maps the Left
side of an Either
value to a new Either
value.
Signature
export declare const mapLeft: {
<L, L2>(f: (left: L) => L2): <R>(self: Either<R, L>) => Either<R, L2>
<R, L, L2>(self: Either<R, L>, f: (left: L) => L2): Either<R, L2>
}
Added in v2.0.0
models
Either (type alias)
Signature
export type Either<R, L = never> = Left<L, R> | Right<L, R>
Added in v2.0.0
EitherUnify (interface)
Signature
export interface EitherUnify<A extends { [Unify.typeSymbol]?: any }> {
Either?: () => A[Unify.typeSymbol] extends Either<infer R0, infer L0> | infer _ ? Either<R0, L0> : never
}
Added in v2.0.0
EitherUnifyIgnore (interface)
Signature
export interface EitherUnifyIgnore {}
Added in v2.0.0
Left (interface)
Signature
export interface Left<out L, out R> extends Pipeable, Inspectable {
readonly _tag: "Left"
readonly _op: "Left"
readonly left: L
readonly [TypeId]: {
readonly _R: Covariant<R>
readonly _L: Covariant<L>
}
[Unify.typeSymbol]?: unknown
[Unify.unifySymbol]?: EitherUnify<this>
[Unify.ignoreSymbol]?: EitherUnifyIgnore
}
Added in v2.0.0
Right (interface)
Signature
export interface Right<out L, out R> extends Pipeable, Inspectable {
readonly _tag: "Right"
readonly _op: "Right"
readonly right: R
readonly [TypeId]: {
readonly _R: Covariant<R>
readonly _L: Covariant<L>
}
[Unify.typeSymbol]?: unknown
[Unify.unifySymbol]?: EitherUnify<this>
[Unify.ignoreSymbol]?: EitherUnifyIgnore
}
Added in v2.0.0
pattern matching
match
Takes two functions and an Either
value, if the value is a Left
the inner value is applied to the onLeft function, if the value is a
Rightthe inner value is applied to the
onRight` function.
Signature
export declare const match: {
<L, B, R, C = B>(options: {
readonly onLeft: (left: L) => B
readonly onRight: (right: R) => C
}): (self: Either<R, L>) => B | C
<R, L, B, C = B>(
self: Either<R, L>,
options: { readonly onLeft: (left: L) => B; readonly onRight: (right: R) => C }
): B | C
}
Example
import * as E from "effect/Either"
import { pipe } from "effect/Function"
const onLeft = (strings: ReadonlyArray<string>): string => `strings: ${strings.join(", ")}`
const onRight = (value: number): string => `Ok: ${value}`
assert.deepStrictEqual(pipe(E.right(1), E.match({ onLeft, onRight })), "Ok: 1")
assert.deepStrictEqual(
pipe(E.left(["string 1", "string 2"]), E.match({ onLeft, onRight })),
"strings: string 1, string 2"
)
Added in v2.0.0
sequencing
andThen
Executes a sequence of two Either
s. The second Either
can be dependent on the result of the first Either
.
Signature
export declare const andThen: {
<R, R2, L2>(f: (right: R) => Either<R2, L2>): <L>(self: Either<R, L>) => Either<R2, L2 | L>
<R2, L2>(f: Either<R2, L2>): <L, R1>(self: Either<R1, L>) => Either<R2, L2 | L>
<R, R2>(f: (right: R) => R2): <L>(self: Either<R, L>) => Either<R2, L>
<R2>(right: NotFunction<R2>): <R1, L>(self: Either<R1, L>) => Either<R2, L>
<R, L, R2, L2>(self: Either<R, L>, f: (right: R) => Either<R2, L2>): Either<R2, L | L2>
<R, L, R2, L2>(self: Either<R, L>, f: Either<R2, L2>): Either<R2, L | L2>
<R, L, R2>(self: Either<R, L>, f: (right: R) => R2): Either<R2, L>
<R, L, R2>(self: Either<R, L>, f: NotFunction<R2>): Either<R2, L>
}
Added in v2.0.0
flatMap
Signature
export declare const flatMap: {
<R, R2, L2>(f: (right: R) => Either<R2, L2>): <L>(self: Either<R, L>) => Either<R2, L2 | L>
<R, L, R2, L2>(self: Either<R, L>, f: (right: R) => Either<R2, L2>): Either<R2, L | L2>
}
Added in v2.0.0
symbols
TypeId
Signature
export declare const TypeId: typeof TypeId
Added in v2.0.0
TypeId (type alias)
Signature
export type TypeId = typeof TypeId
Added in v2.0.0
type lambdas
EitherTypeLambda (interface)
Signature
export interface EitherTypeLambda extends TypeLambda {
readonly type: Either<this["Target"], this["Out1"]>
}
Added in v2.0.0
utils
Either (namespace)
Added in v2.0.0
Left (type alias)
Signature
export type Left<T extends Either<any, any>> = [T] extends [Either<infer _A, infer _E>] ? _E : never
Added in v2.0.0
Right (type alias)
Signature
export type Right<T extends Either<any, any>> = [T] extends [Either<infer _A, infer _E>] ? _A : never
Added in v2.0.0
zipping
zipWith
Signature
export declare const zipWith: {
<R2, L2, R, B>(that: Either<R2, L2>, f: (right: R, right2: R2) => B): <L>(self: Either<R, L>) => Either<B, L2 | L>
<R, L, R2, L2, B>(self: Either<R, L>, that: Either<R2, L2>, f: (right: R, right2: R2) => B): Either<B, L | L2>
}
Added in v2.0.0