export type Option<T> = | { value: T; isSome: true; } | { value: undefined; isSome: false; }; export function Some<T>(value: T): Option<T> { return { value, isSome: true }; } export function None<T>(): Option<T> { return { value: undefined, isSome: false }; } export function map<T, U>(option: Option<T>, fn: (value: T) => U): Option<U> { return option.isSome ? Some(fn(option.value)) : None(); } export function flatMap<T, U>( option: Option<T>, fn: (value: T) => Option<U>, ): Option<U> { return option.isSome ? fn(option.value) : None(); } export function getOrElse<T>(option: Option<T>, defaultValue: T): T { return option.isSome ? option.value : defaultValue; } export function fold<T, U>( option: Option<T>, onNone: () => U, onSome: (value: T) => U, ): U { return option.isSome ? onSome(option.value) : onNone(); }