import type { Either } from "../Either"; import type { Lazy } from "../Function"; import { fromNullable, none, some } from "./constructors"; import { isNone } from "./guards"; import type { Option } from "./model"; /* * ------------------------------------------- * Option Combinators * ------------------------------------------- */ /** * mapNullable_ :: Maybe m => (m a, (a -> ?b)) -> m b * Map over a Maybe with a function that returns a nullable value * * @category Combinators * @since 1.0.0 */ export const mapNullable_ = (fa: Option, f: (a: A) => B | null | undefined): Option => isNone(fa) ? none() : fromNullable(f(fa.value)); /** * mapNullable :: Maybe m => (a -> ?b) -> m a -> m b * Map over a Maybe with a function that returns a nullable value * * @category Combinators * @since 1.0.0 */ export const mapNullable: (f: (a: A) => B | null | undefined) => (fa: Option) => Option = (f) => (fa) => mapNullable_(fa, f); /** * orElse_ :: Maybe m => (m a, () -> m b) -> m (a | b) * Evaluate and return alternate optional value if empty * * @category Combinators * @since 1.0.0 */ export const orElse_ = (fa: Option, onNothing: Lazy>): Option => isNone(fa) ? onNothing() : fa; /** * orElse :: Maybe m => (() -> m b) -> m a -> m (a | b) * Evaluate and return alternate optional value if empty * * @category Combinators * @since 1.0.0 */ export const orElse = (onNothing: Lazy>) => (fa: Option): Option => orElse_(fa, onNothing); /** * getLeft :: (Either e, Maybe m) => e a b -> m a * Evaluates an `Either` and returns a `Maybe` carrying the left value, if it exists * * @category Combinators * @since 1.0.0 */ export const getLeft = (fea: Either): Option => (fea._tag === "Right" ? none() : some(fea.left)); /** * getRight :: (Either e, Maybe m) => e a b -> m b * Evaluates an `Either` and returns a `Maybe` carrying the right value, if it exists * * @category Combinators * @since 1.0.0 */ export const getRight = (fea: Either): Option => (fea._tag === "Left" ? none() : some(fea.right));