import { identity } from "../Function"; import { isLeft } from "./guards"; import type { Either } from "./model"; /* * ------------------------------------------- * Either Destructors * ------------------------------------------- */ /** * ```haskell * _fold :: (Either e a, (e -> b), (a -> c)) -> b | c * ``` * * 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. * * @category Destructors * @since 1.0.0 */ export const fold_ = (pab: Either, onLeft: (e: E) => B, onRight: (a: A) => C): B | C => isLeft(pab) ? onLeft(pab.left) : onRight(pab.right); /** * ```haskell * fold :: ((e -> b), (a -> c)) -> Either e a -> b | c * ``` * * 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. * * @category Destructors * @since 1.0.0 */ export const fold = (onLeft: (e: E) => B, onRight: (a: A) => C) => (pab: Either): B | C => fold_(pab, onLeft, onRight); /** * ```haskell * either :: ((e -> b), (a -> c)) -> Either e a -> b | c * ``` */ export const either = fold; /** * ```haskell * _getOrElse :: (Either e a, (e -> b)) -> a | b * ``` * * @category Destructors * @since 1.0.0 */ export const getOrElse_ = (pab: Either, onLeft: (e: E) => B): A | B => isLeft(pab) ? onLeft(pab.left) : pab.right; /** * ```haskell * _getOrElse :: (e -> b) -> Either e a -> a | b * ``` * * @category Destructors * @since 1.0.0 */ export const getOrElse = (f: (e: E) => B) => (pab: Either) => getOrElse_(pab, f); /** * ```haskell * merge :: Either e a -> e | a * ``` * * @category Destructors * @since 1.0.0 */ export const merge = (pab: Either): E | A => fold_(pab, identity, identity as any);