import { Algebra, Foldable, Functor, Monad } from './index.js' /** @import { Morphism } from './types.js' */ /** * @template T, E */ export class Ok extends Algebra(Monad, Foldable) { /** @type {T} */ #value /** * @param {T} value * @constructs {Ok} */ constructor(value) { super() this.#value = value } /** @returns {this is Ok} */ isOk() { return true } /** @returns {this is Err} */ isErr() { return false } /** * @template R * @param {Morphism} f * @this {Ok} * @returns {R} */ chain(f) { return f(this.#value) } /** * @template R * @param {Morphism} f * @this {Ok} * @returns {Ok} */ map(f) { return Result.of(this.chain(f)) } /** * @template R * @param {Morphism} f * @this {Ok} * @returns {Ok} */ then(f) { return this.map(f) } /** * @template R * @param {Morphism} _f * @returns {this} */ catch(_f) { return this } /** * @template U * @param {(acc: U, value: T) => U} f * @param {U} init * @returns {U} */ reduce(f, init) { return f(init, this.#value) } } /** * @template T, E */ export class Err extends Algebra(Functor, Monad) { /** @type {E} */ #value /** * @param {E} value * @constructs {Err} */ constructor(value) { super() this.#value = value } /** @returns {this is Ok} */ isOk() { return false } /** @returns {this is Err} */ isErr() { return true } /** * @template R * @param {Morphism} _f * @returns {this} */ chain(_f) { return this } /** * @template R * @param {Morphism} _f * @returns {this} */ map(_f) { return this } /** * @template R * @param {Morphism} _f * @returns {this} */ then(_f) { return this } /** * @template R * @param {Morphism} f * @returns {Err} */ catch(f) { return new Err(f(this.#value)) } /** * @template U * @param {(acc: U, value: T) => U} _f * @param {U} init * @returns {U} */ reduce(_f, init) { return init } } /** * @template T, E * @type {Ok | Err} Result */ export class Result { /** * @template T * @param {T} value * @returns {Ok} */ static of(value) { return new Ok(value) } } /** * @template T, E * @param {T} v * @returns {Ok} */ export const ok = v => new Ok(v) /** * @template T, E * @param {E} e * @returns {Err} */ export const err = e => new Err(e)