import { ErrorMessage } from "../errors/messages.js"; export type result = | { ok: true; value: V; } | { ok: false; value: E }; export function Ok(value: T): result { return { ok: true, value: value }; } export function Err(value: E): result { return { ok: false, value: value }; } export function fmap( r: result, fn: (v: T) => T2 ): result { if (r.ok) { return Ok(fn(r.value)); } else { return r; } } export function fmap2( r: result, fn1: (v: T) => T2, fn2: (v: E) => E2 ): result { if (r.ok) { return Ok(fn1(r.value)); } else { return Err(fn2(r.value)); } } export function errMap( r: result, fn: (v: E) => E2 ): result { if (r.ok) { return r; } else { return Err(fn(r.value)); } } export function bind( r: result, fn: (v: T) => result ): result { if (r.ok) { return fn(r.value); } else { return r; } } export function merge( a: result, b: result ): result<[T1, T2], E> { if (!a.ok) { return a; } if (!b.ok) { return b; } return Ok([a.value, b.value]); } export function mergeMany(results: result[]): result { const values: T[] = []; for (const result of results) { if (result.ok) { values.push(result.value); } else { return Err(result.value); } } return Ok(values); } export function getError(r: result): E | undefined { if (!r.ok) { return r.value; } else { return undefined; } } export function getExt(r: result): T { if (r.ok) { return r.value; } else { throw r.value; } } export function getOrThrow( r: result, errMap: (e: E) => ErrorMessage ): T { if (!r.ok) { throw errMap(r.value); } else { return r.value; } }