Overview

Represents a value of one of two possible types (a disjoint union).

An instance of Either is either an instance of Left or Right.

A common use of Either is as an alternative to Option for dealing with possible missing values. In this usage, None is replaced with a Left which can contain useful information. Right takes the place of Some. Convention dictates that Left is used for failure and Right is used for success.

For example, you could use Either<string, number> to detect whether a received input is a string or a number.

const parse = (errorMessage: string) => (input: string): Either<string, number> => {
  const n = parseInt(input, 10)
  return isNaN(n) ? left(errorMessage) : right(n)
}

Either is right-biased, which means that Right is assumed to be the default case to operate on. If it is Left, operations like map, chain, … return the Left value unchanged:

right(12).map(double) // right(24)
left(23).map(double) // left(23)

Table of contents


Either (type alias)

Signature

export type Either<L, A> = Left<L, A> | Right<L, A>

Added in v1.0.0

URI (type alias)

Signature

export type URI = typeof URI

Left (class)

Left side of Either

Signature

export class Left<L, A> {
  constructor(readonly value: L) { ... }
  ...
}

map (method)

The given function is applied if this is a Right

Signature

map<B>(f: (a: A) => B): Either<L, B> { ... }

ap (method)

Signature

ap<B>(fab: Either<L, (a: A) => B>): Either<L, B> { ... }

ap_ (method)

Flipped version of ap

Signature

ap_<B, C>(this: Either<L, (b: B) => C>, fb: Either<L, B>): Either<L, C> { ... }

chain (method)

Binds the given function across Right

Signature

chain<B>(f: (a: A) => Either<L, B>): Either<L, B> { ... }

bimap (method)

Signature

bimap<V, B>(f: (l: L) => V, g: (a: A) => B): Either<V, B> { ... }

alt (method)

Signature

alt(fy: Either<L, A>): Either<L, A> { ... }

orElse (method)

Lazy version of alt

Signature

orElse<M>(fy: (l: L) => Either<M, A>): Either<M, A> { ... }

Example

import { right } from 'fp-ts/lib/Either'

assert.deepStrictEqual(right(1).orElse(() => right(2)), right(1))

Added in v1.6.0

extend (method)

Signature

extend<B>(f: (ea: Either<L, A>) => B): Either<L, B> { ... }

reduce (method)

Signature

reduce<B>(b: B, f: (b: B, a: A) => B): B { ... }

fold (method)

Applies a function to each case in the data structure

Signature

fold<B>(onLeft: (l: L) => B, onRight: (a: A) => B): B { ... }

getOrElse (method)

Returns the value from this Right or the given argument if this is a Left

Signature

getOrElse(a: A): A { ... }

getOrElseL (method)

Returns the value from this Right or the result of given argument if this is a Left

Signature

getOrElseL(f: (l: L) => A): A { ... }

mapLeft (method)

Maps the left side of the disjunction

Signature

mapLeft<M>(f: (l: L) => M): Either<M, A> { ... }

inspect (method)

Signature

inspect(): string { ... }

toString (method)

Signature

toString(): string { ... }

isLeft (method)

Returns true if the either is an instance of Left, false otherwise

Signature

isLeft(): this is Left<L, A> { ... }

isRight (method)

Returns true if the either is an instance of Right, false otherwise

Signature

isRight(): this is Right<L, A> { ... }

swap (method)

Swaps the disjunction values

Signature

swap(): Either<A, L> { ... }

filterOrElse (method)

Returns Right with the existing value of Right if this is a Right and the given predicate p holds for the right value, returns Left(zero) if this is a Right and the given predicate p does not hold for the right value, returns Left with the existing value of Left if this is a Left.

Signature

filterOrElse<B extends A>(p: Refinement<A, B>, zero: L): Either<L, B>
filterOrElse(p: Predicate<A>, zero: L): Either<L, A> { ... }

Example

import { right, left } from 'fp-ts/lib/Either'

assert.deepStrictEqual(right(12).filterOrElse(n => n > 10, -1), right(12))
assert.deepStrictEqual(right(7).filterOrElse(n => n > 10, -1), left(-1))
assert.deepStrictEqual(left(12).filterOrElse(n => n > 10, -1), left(12))

Added in v1.3.0

filterOrElseL (method)

Lazy version of filterOrElse

Signature

filterOrElseL<B extends A>(p: Refinement<A, B>, zero: (a: A) => L): Either<L, B>
filterOrElseL(p: Predicate<A>, zero: (a: A) => L): Either<L, A> { ... }

Added in v1.3.0

refineOrElse (method)

Use filterOrElse instead

Signature

refineOrElse<B extends A>(p: Refinement<A, B>, zero: L): Either<L, B> { ... }

Added in v1.6.0

refineOrElseL (method)

Lazy version of refineOrElse Use filterOrElseL instead

Signature

refineOrElseL<B extends A>(p: Refinement<A, B>, zero: (a: A) => L): Either<L, B> { ... }

Added in v1.6.0

Right (class)

Right side of Either

Signature

export class Right<L, A> {
  constructor(readonly value: A) { ... }
  ...
}

map (method)

Signature

map<B>(f: (a: A) => B): Either<L, B> { ... }

ap (method)

Signature

ap<B>(fab: Either<L, (a: A) => B>): Either<L, B> { ... }

ap_ (method)

Signature

ap_<B, C>(this: Either<L, (b: B) => C>, fb: Either<L, B>): Either<L, C> { ... }

chain (method)

Signature

chain<B>(f: (a: A) => Either<L, B>): Either<L, B> { ... }

bimap (method)

Signature

bimap<V, B>(f: (l: L) => V, g: (a: A) => B): Either<V, B> { ... }

alt (method)

Signature

alt(fy: Either<L, A>): Either<L, A> { ... }

orElse (method)

Signature

orElse<M>(fy: (l: L) => Either<M, A>): Either<M, A> { ... }

extend (method)

Signature

extend<B>(f: (ea: Either<L, A>) => B): Either<L, B> { ... }

reduce (method)

Signature

reduce<B>(b: B, f: (b: B, a: A) => B): B { ... }

fold (method)

Signature

fold<B>(onLeft: (l: L) => B, onRight: (a: A) => B): B { ... }

getOrElse (method)

Signature

getOrElse(a: A): A { ... }

getOrElseL (method)

Signature

getOrElseL(f: (l: L) => A): A { ... }

mapLeft (method)

Signature

mapLeft<M>(f: (l: L) => M): Either<M, A> { ... }

inspect (method)

Signature

inspect(): string { ... }

toString (method)

Signature

toString(): string { ... }

isLeft (method)

Signature

isLeft(): this is Left<L, A> { ... }

isRight (method)

Signature

isRight(): this is Right<L, A> { ... }

swap (method)

Signature

swap(): Either<A, L> { ... }

filterOrElse (method)

Signature

filterOrElse<B extends A>(p: Refinement<A, B>, zero: L): Either<L, B>
filterOrElse(p: Predicate<A>, zero: L): Either<L, A> { ... }

filterOrElseL (method)

Signature

filterOrElseL<B extends A>(p: Refinement<A, B>, zero: (a: A) => L): Either<L, B>
filterOrElseL(p: Predicate<A>, zero: (a: A) => L): Either<L, A> { ... }

refineOrElse (method)

Signature

refineOrElse<B extends A>(p: Refinement<A, B>, zero: L): Either<L, B> { ... }

refineOrElseL (method)

Signature

refineOrElseL<B extends A>(p: Refinement<A, B>, zero: (a: A) => L): Either<L, B> { ... }

URI (constant)

Signature

export const URI = ...

either (constant)

Signature

export const either: Monad2<URI> &
  Foldable2v2<URI> &
  Traversable2v2<URI> &
  Bifunctor2<URI> &
  Alt2<URI> &
  Extend2<URI> &
  ChainRec2<URI> = ...

Added in v1.0.0

fromNullable (function)

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

Signature

export const fromNullable = <L>(defaultValue: L) => <A>(a: A | null | undefined): Either<L, A> => ...

Added in v1.0.0

fromOption (function)

Takes a default and a Option value, if the value is a Some, turn it into a Right, if the value is a None use the provided default as a Left

Signature

export const fromOption = <L>(defaultValue: L) => <A>(fa: Option<A>): Either<L, A> => ...

Added in v1.0.0

fromOptionL (function)

Lazy version of fromOption

Signature

export const fromOptionL = <L>(defaultValue: Lazy<L>) => <A>(fa: Option<A>): Either<L, A> => ...

Added in v1.3.0

fromPredicate (function)

Signature

export function fromPredicate<L, A, B extends A>(
  predicate: Refinement<A, B>,
  onFalse: (a: A) => L
): (a: A) => Either<L, B>
export function fromPredicate<L, A>(predicate: Predicate<A>, onFalse: (a: A) => L): (a: A) => Either<L, A> { ... }

Added in v1.0.0

fromRefinement (function)

Use fromPredicate instead

Signature

export const fromRefinement = <L, A, B extends A>(refinement: Refinement<A, B>, onFalse: (a: A) => L) => (
  a: A
): Either<L, B> => ...

Added in v1.6.0

fromValidation (function)

Signature

export const fromValidation = <L, A>(fa: Validation<L, A>): Either<L, A> => ...

Added in v1.0.0

getApplyMonoid (function)

Signature

export const getApplyMonoid = <L, A>(M: Monoid<A>): Monoid<Either<L, A>> => ...

Added in v1.7.0

getApplySemigroup (function)

Apply semigroup

Signature

export const getApplySemigroup = <L, A>(S: Semigroup<A>): Semigroup<Either<L, A>> => ...

Example

import { getApplySemigroup, left, right } from 'fp-ts/lib/Either'
import { semigroupSum } from 'fp-ts/lib/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))

Added in v1.7.0

getCompactable (function)

Builds Compactable instance for Either given Monoid for the left side

Signature

export function getCompactable<L>(ML: Monoid<L>): Compactable2C<URI, L> { ... }

Added in v1.7.0

getFilterable (function)

Builds Filterable instance for Either given Monoid for the left side

Signature

export function getFilterable<L>(ML: Monoid<L>): Filterable2C<URI, L> { ... }

Added in v1.7.0

getSemigroup (function)

Semigroup returning the left-most non-Left value. If both operands are Rights then the inner values are appended using the provided Semigroup

Signature

export const getSemigroup = <L, A>(S: Semigroup<A>): Semigroup<Either<L, A>> => ...

Example

import { getSemigroup, left, right } from 'fp-ts/lib/Either'
import { semigroupSum } from 'fp-ts/lib/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))

Added in v1.7.0

getSetoid (function)

Signature

export const getSetoid = <L, A>(SL: Setoid<L>, SA: Setoid<A>): Setoid<Either<L, A>> => ...

Added in v1.0.0

getWitherable (function)

Builds Witherable instance for Either given Monoid for the left side

Signature

export function getWitherable<L>(ML: Monoid<L>): Witherable2C<URI, L> { ... }

Added in v1.7.0

isLeft (function)

Returns true if the either is an instance of Left, false otherwise

Signature

export const isLeft = <L, A>(fa: Either<L, A>): fa is Left<L, A> => ...

Added in v1.0.0

isRight (function)

Returns true if the either is an instance of Right, false otherwise

Signature

export const isRight = <L, A>(fa: Either<L, A>): fa is Right<L, A> => ...

Added in v1.0.0

left (function)

Constructs a new Either holding a Left value. This usually represents a failure, due to the right-bias of this structure

Signature

export const left = <L, A>(l: L): Either<L, A> => ...

Added in v1.0.0

right (function)

Constructs a new Either holding a Right value. This usually represents a successful value due to the right bias of this structure

Signature

export const right = <L, A>(a: A): Either<L, A> => ...

Added in v1.0.0

toError (function)

Default value for the optional onerror argument of tryCatch

Signature

export const toError = (e: unknown): Error => ...

Added in v1.0.0

tryCatch (function)

Use tryCatch2v instead

Signature

export const tryCatch = <A>(f: Lazy<A>, onerror: (e: unknown) => Error = toError): Either<Error, A> => ...

Added in v1.0.0

tryCatch2v (function)

Constructs a new Either from a function that might throw

Signature

export const tryCatch2v = <L, A>(f: Lazy<A>, onerror: (e: unknown) => L): Either<L, A> => ...

Example

import { Either, left, right, tryCatch2v } from 'fp-ts/lib/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 tryCatch2v(() => 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))

Added in v1.11.0