Skip to content

Latest commit

 

History

History
468 lines (262 loc) · 6.97 KB

README.md

File metadata and controls

468 lines (262 loc) · 6.97 KB

@typed/either -- 4.0.0

Well-typed Either data-structure

Get it

yarn add @typed/either
# or
npm install --save @typed/either

API Documentation

All functions are curried!

Either

Either data structure. Extremely useful for handling errors or different logic paths without the use of if-statements.

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

Either.left<A, B = any>(value: A): Either<A, B>

Creates an Either<A, B> that is of type Left<A>

See the code
export const left: <A, B = any>(value: A) => Either<A, B> = Left.of
}

Either.of<A, B = any>(value: A): Either<B, A>

Creates an Either<A, B> that is of type Right<B>

See the code
export const of: <A, B = any>(value: A) => Either<B, A> = Right.of

Left

A JSON-serializable Left<A> data-structure.

export interface Left<A> {
  readonly '@typed/Left': A
}

Left.of<A>(value: A): Left<A>

Create a Left<A>

See the code
export function of<A>(value: A): Left<A> {
  return { '@typed/Left': value }
}
}

Right

A JSON-serializable Right data-structure.

export interface Right<A> {
  readonly '@typed/Right': A
}

Right.of<A>(value: A): Right<A>

Creates a Right

See the code
export function of<A>(value: A): Right<A> {
  return { '@typed/Right': value }
}
}

ap<A, B, C>(fn: Either<A, (value: B) => C>, value: Either<A, B>): Either<A, C>

Applies the function contains in an Either to the value contained in a second Either.

See the code
export const ap: EitherAp = curry2(__ap)

function __ap<A, B, C>(fn: Either<A, (value: B) => C>, value: Either<A, B>): Either<A, C> {
  return chain(f => map(f, value), fn)
}

export type EitherAp = {
  <A, B, C>(fn: Either<A, (value: B) => C>, value: Either<A, B>): Either<A, C>
  <A, B, C>(fn: Either<A, (value: B) => C>): (value: Either<A, B>) => Either<A, C>
}

chain<A, B, C>(f: (value: B) => Either<A, C>, either: Either<A, B>): Either<A C>

Returns a Either that is the result of calling f with the resolved value of another Either.

See the code
export const chain: EitherChain = curry2(__chain)

function __chain<A, B, C>(f: (value: B) => Either<A, C>, either: Either<A, B>): Either<A, C> {
  return isLeft(either) ? either : f(fromRight(either))
}

export type EitherChain = {
  <A, B, C>(f: (value: B) => Either<A, C>, either: Either<A, B>): Either<A, C>
  <A, B, C>(f: (value: B) => Either<A, C>): (either: Either<A, B>) => Either<A, C>
}

chainLeft<A, B, C>(f: (value: B) => Either<C, B>, either: Either<A, B>): Either<A C>

Returns a Either that is the result of calling f with the rejected value of another Either.

See the code
export const chainLeft: EitherChainLeft = curry2(__chainLeft)

function __chainLeft<A, B, C>(f: (value: A) => Either<C, B>, either: Either<A, B>): Either<C, B> {
  return isLeft(either) ? f(fromLeft(either)) : either
}

export type EitherChainLeft = {
  <A, B, C>(f: (value: A) => Either<C, B>, either: Either<A, B>): Either<C, B>
  <A, B, C>(f: (value: A) => Either<C, B>): (either: Either<A, B>) => Either<C, B>
}

fromLeft<A>(left: Left<A>): A

Extracts the value contained in a Left.

See the code
export function fromLeft<A>(left: Left<A>): A {
  return left['@typed/Left']
}

fromRight<A>(right: Right<A>): A

Extracts the value contained in a Right.

See the code
export function fromRight<A>(right: Right<A>): A {
  return right['@typed/Right']
}

isLeft<A, B>(either: Either<A, B>): Either is Left<A>

Returns true if an Either<A, B> is type Left<A>

See the code
export function isLeft<A, B>(either: Either<A, B>): either is Left<A> {
  return either.hasOwnProperty('@typed/Left')
}

isRight<A, B>(either: Either<A, B>): either is Right<B>

Returns true if an Either<A, B> is type Right<B>

See the code
export function isRight<A, B>(either: Either<A, B>): either is Right<B> {
  return either.hasOwnProperty('@typed/Right')
}

map<A, B, C>(f: (value: B) => C, either: Either<A, B>): Either<A C>

Returns a Either that is the result of calling f with the resolved value of another Either.

See the code
export const map: EitherMap = curry2(__map)

function __map<A, B, C>(f: (value: B) => C, either: Either<A, B>): Either<A, C> {
  return chain(value => Either.of(f(value)), either)
}

export type EitherMap = {
  <A, B, C>(f: (value: B) => C, either: Either<A, B>): Either<A, C>
  <A, B, C>(f: (value: B) => C): (either: Either<A, B>) => Either<A, C>
}

mapLeft<A, B, C>(f: (value: A) => C, either: Either<A, B>): Either<A C>

Returns a Either that is the result of calling f with the resolved value of another Either.

See the code
export const mapLeft: EitherMapLeft = curry2(__mapLeft)

function __mapLeft<A, B, C>(f: (value: A) => C, either: Either<A, B>): Either<C, B> {
  return chainLeft(value => Either.left(f(value)), either)
}

export type EitherMapLeft = {
  <A, B, C>(f: (value: A) => C, either: Either<A, B>): Either<C, B>
  <A, B, C>(f: (value: A) => C): (either: Either<A, B>) => Either<C, B>
}

swap<A, B>(either: Either<A, B>): Either<B, A>

Swaps the values contained in an Either.

See the code
export function swap<A, B>(either: Either<A, B>): Either<B, A> {
  return isLeft(either) ? Either.of(fromLeft(either)) : Either.left(fromRight(either))
}

unpack<A, B, C>(f: Arity1<A, C>, g: Arity1<B, C>, either: Either<A, B>): C

Extracts the value from an Either applying function f if the Either\<A, B\> is Left\<A\> or function g if Right\<B\>.

See the code
export const unpack: Unpack = curry3(__unpack)

function __unpack<A, B, C>(f: (value: A) => C, g: (value: B) => C, either: Either<A, B>): C {
  return isLeft(either) ? f(fromLeft(either)) : g(fromRight(either))
}