import type * as P from "@principia/prelude"; import * as HKT from "@principia/prelude/HKT"; import { flow, identity } from "../Function"; import { fail, succeed } from "./constructors"; import { catchAll_ } from "./fold"; import type { Async, URI, V } from "./model"; import { ChainInstruction } from "./model"; import { unit } from "./unit"; /* * ------------------------------------------- * Monad Async * ------------------------------------------- */ export const chain_ = (ma: Async, f: (a: A) => Async): Async => new ChainInstruction(ma, f); export const chain = (f: (a: A) => Async) => (ma: Async): Async => new ChainInstruction(ma, f); export const flatten: (mma: Async>) => Async = chain( identity ); export const tap_ = (ma: Async, f: (a: A) => Async): Async => chain_(ma, (a) => chain_(f(a), (_) => succeed(a))); export const tap = (f: (a: A) => Async) => (ma: Async): Async => tap_(ma, f); export const tapError_ = ( async: Async, f: (e: E) => Async ): Async => catchAll_(async, (e) => chain_(f(e), (_) => fail(e))); export const tapError = (f: (e: E) => Async) => ( async: Async ): Async => tapError_(async, f); export const Monad: P.Monad<[URI], V> = HKT.instance({ map_: (fa, f) => chain_(fa, flow(f, succeed)), map: (f) => chain(flow(f, succeed)), unit, flatten });