import type { Either } from "../Either"; import type { FunctionN, Lazy, Predicate, Refinement } from "../Function"; import type { IO } from "../IO"; import type { Option } from "../Option"; import * as X from "../XPure"; import { fail, fromEither, succeed } from "./constructors"; import type { EIO } from "./model"; import { chain_ } from "./monad"; /* * ------------------------------------------- * EIO Combinators * ------------------------------------------- */ export const foldM_: ( ma: EIO, onFailure: (e: E) => EIO, onSuccess: (a: A) => EIO ) => EIO = X.foldM_; export const foldM: ( onFailure: (e: E) => EIO, onSuccess: (a: A) => EIO ) => (ma: EIO) => EIO = X.foldM; export const fold_ = (ma: EIO, onFailure: (e: E) => IO, onSuccess: (a: A) => IO): IO => foldM_(ma, onFailure, onSuccess); export const fold = (onLeft: (e: E) => IO, onRight: (a: A) => IO) => (ma: EIO) => fold_(ma, onLeft, onRight); export const orElse_: (ma: EIO, onLeft: (e: E) => EIO) => EIO = X.orElse_; export const orElse = (onLeft: (e: E) => EIO) => (ma: EIO) => orElse_(ma, onLeft); export const filterOrElse_: { (ma: EIO, refinement: Refinement, onFalse: (a: A) => E1): EIO; (ma: EIO, predicate: Predicate, onFalse: (a: A) => E1): EIO; } = (ma: EIO, predicate: Predicate, onFalse: (a: A) => E1): EIO => chain_(ma, (a) => (predicate(a) ? succeed(a) : fail(onFalse(a)))); export const filterOrElse: { (refinement: Refinement, onFalse: (a: A) => E1): (ma: EIO) => EIO; (predicate: Predicate, onFalse: (a: A) => E1): (ma: EIO) => EIO; } = (predicate: Predicate, onFalse: (a: A) => E1) => (ma: EIO) => filterOrElse_(ma, predicate, onFalse); export const fromEitherK = , E, B>( f: FunctionN> ): ((...args: A) => EIO) => (...a) => fromEither(f(...a)); export const chainEitherK_ = (ma: EIO, f: (a: A) => Either) => chain_(ma, fromEitherK(f)); export const chainEitherK = (f: (a: A) => Either) => (ma: EIO) => chainEitherK_(ma, f); export const fromOption_ = (ma: Option, onNone: Lazy): EIO => ma._tag === "None" ? fail(onNone()) : succeed(ma.value); export const fromOption = (onNone: Lazy) => (ma: Option) => fromOption_(ma, onNone);