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));