/** * Naive "either or" type implementation. * * This differs from other implementations mostly in how relaxed the type inferrence is. * * Again, this could easily be replaced with something from e.g. fp-ts, but the goal is * to have a single "prelude/stdlib" here. * * * @module * @deprecated use effect instead */ import { identity } from "./Function.js"; export type Either = | { __tag: "left"; left: Left } | { __tag: "right"; right: Right }; export type Left> = E extends Either ? Left : never; export type Right> = E extends Either ? Right : never; export const left = (left: Left): Either => ({ __tag: "left", left, }); export const right = (right: Right): Either => ({ __tag: "right", right, }); export const map = (fn: (value: R1) => R2) => (either: Either): Either => either.__tag === "left" ? either : { __tag: "right", right: fn(either.right) }; export const flatMap = >(fn: (value: R1) => E) => (either: Either): Either>, Right>> => either.__tag === "left" ? either : fn(either.right); export const match = (onLeft: (left: Left) => T, onRight: (right: Right) => T) => (either: Either): T => either.__tag === "left" ? onLeft(either.left) : onRight(either.right); export const getOrElse = (fallback: (left: L) => F) => match(fallback, identity); export const alt = (second: Either) => (first: Either) => first.__tag === "right" ? first : second;