import { Lazy } from './Lazy'; export interface None { readonly tag: 'None'; } export interface Some { readonly tag: 'Some'; readonly value: A; } export type Option = None | Some; export const none: Option = { tag: 'None' }; export const some = (a: A): Option => ({ tag: 'Some', value: a }); export const isSome = (ma: Option): ma is Some => ma.tag === 'Some'; export const isNone = (ma: Option): ma is None => ma.tag === 'None'; export function fromUndefinedable(a: A): Option> { return a === undefined ? none : some(a as NonNullable); } export function fromNullable(a: A): Option> { return a === null ? none : some(a as NonNullable); } export function fromNillable(a: A): Option> { return a === null || a === undefined ? none : some(a as NonNullable); } export function toNullable(ma: Option): A | null { return isNone(ma) ? null : ma.value; } export function toUndefinedable(ma: Option): A | undefined { return isNone(ma) ? undefined : ma.value; } export const map = (f: (a: A) => B) => (ma: Option) => isNone(ma) ? none : some(f(ma.value)); export const flatMap = (f: (a: A) => Option) => (ma: Option) => { if (isNone(ma)) { return none; } const mb = f(ma.value); if (isNone(mb)) { return none; } return some(mb.value); }; export const getOrElse = (onNone: Lazy) => (mb: Option): A | B => isNone(mb) ? onNone() : mb.value;