import type { Either } from "../Either"; import type { FunctionN, Lazy, Predicate, Refinement } from "../Function"; import type { Option } from "./model"; /* * ------------------------------------------- * Constructors * ------------------------------------------- */ /** * ```haskell * nothing :: () -> Nothing * ``` * * Constructs a new `Maybe` holding no value (a.k.a `Nothing`) * * @category Constructors * @since 1.0.0 */ export const none = (): Option => ({ _tag: "None" }); /** * ```haskell * just :: a -> Just a * ``` * * Constructs a new `Maybe` holding a `Just` value. * * @category Constructs * @since 1.0.0 */ export const some = (a: A): Option => ({ _tag: "Some", value: a }); /** * ```haskell * fromNullable :: ?a -> Maybe a * ``` * * Constructs a new `Maybe` from a nullable value. If the value is `null` or `undefined`, returns `Nothing`, otherwise * returns the value wrapped in a `Just` * * @category Constructors * @since 1.0.0 */ export const fromNullable = (a: A | null | undefined): Option> => a == null ? none() : some(a as NonNullable); /** * ```haskell * partial :: (() -> a) -> Maybe a * ``` * * Constructs a new `Maybe` from a function that might throw * * @category Constructors * @since 1.0.0 */ export const partial = (thunk: Lazy): Option => { try { return some(thunk()); } catch (_) { return none(); } }; /** * ```haskell * partialK :: ((a, b, ...) -> c) -> ((a, b, ...) -> Maybe c) * ``` * * Transforms a non-curried function that may throw, takes a set of arguments `(a, b, ...)`, and returns a value `c`, into a non-curried function that will not throw, takes a set of arguments `(a, b, ...)`, and returns a `Maybe` * * @category Constructors * @since 1.0.0 */ export const partialK = , B>(f: FunctionN): ((...args: A) => Option) => ( ...a ) => partial(() => f(...a)); /** * ```haskell * fromPredicate_ :: (a, (a -> is b)) -> Maybe b * fromPredicate_ :: (a, (a -> Boolean)) -> Maybe a * ``` * * Constructs a new `Maybe` from a value and the given predicate * * @category Constructors * @since 1.0.0 */ export const fromPredicate_: { (a: A, refinement: Refinement): Option; (a: A, predicate: Predicate): Option; } = (a: A, predicate: Predicate): Option => (predicate(a) ? none() : some(a)); /** * ```haskell * fromPredicate :: (a -> is b) -> a -> Maybe b * fromPredicate :: (a -> Boolean) -> a -> Maybe a * ``` * * Returns a smart constructor based on the given predicate * * @category Constructors * @since 1.0.0 */ export const fromPredicate: { (refinement: Refinement): (a: A) => Option; (predicate: Predicate): (a: A) => Option; } = (predicate: Predicate) => (a: A) => fromPredicate_(a, predicate); /** * ```haskell * fromEither :: Either e a -> Maybe a * ``` * * Constructs a new `Maybe` from an `Either`, transforming a `Left` into a `Nothing` and a `Right` into a `Just`. * * @category Constructors * @since 1.0.0 */ export const fromEither = (ma: Either): Option => (ma._tag === "Left" ? none() : some(ma.right));