import { succeed } from "./constructors"; import type { XPure } from "./model"; import { FoldInstruction } from "./model"; /* * ------------------------------------------- * Fold XPure * ------------------------------------------- */ /** * ```haskell * foldM_ :: ( * XPure s1 s2 r e a, * (e -> XPure s3 s4 r1 e1 b), * (a -> XPure s2 s5 r2 e2 c) * ) -> XPure (s1 & s3) (s4 | s5) (r & r1 & r2) (b | c) * ``` * * Recovers from errors by accepting one computation to execute for the case * of an error, and one computation to execute for the case of success. * * @category Combinators * @since 1.0.0 */ export const foldM_ = ( fa: XPure, onFailure: (e: E) => XPure, onSuccess: (a: A) => XPure ): XPure => new FoldInstruction(fa, onFailure, onSuccess); /** * ```haskell * foldM :: ( * (e -> XPure s3 s4 r1 e1 b), * (a -> XPure s2 s5 r2 e2 c) * ) -> XPure s1 s2 r e a -> XPure (s1 & s3) (s4 | s5) (r & r1 & r2) (b | c) * ``` * * Recovers from errors by accepting one computation to execute for the case * of an error, and one computation to execute for the case of success. * * @category Combinators * @since 1.0.0 */ export const foldM = ( onFailure: (e: E) => XPure, onSuccess: (a: A) => XPure ) => (fa: XPure) => foldM_(fa, onFailure, onSuccess); /** * ```haskell * fold_ :: ( * XPure s1 s2 r e a, * (e -> b), * (a -> c) * ) -> XPure s1 s2 r _ (b | c) * ``` * * Folds over the failed or successful results of this computation to yield * a computation that does not fail, but succeeds with the value of the left * or right function passed to `fold`. * * @category Combinators * @since 1.0.0 */ export const fold_ = ( fa: XPure, onFailure: (e: E) => B, onSuccess: (a: A) => C ): XPure => foldM_( fa, (e) => succeed(onFailure(e)), (a) => succeed(onSuccess(a)) ); /** * ```haskell * fold :: ((e -> b), (a -> c)) -> XPure s1 s2 r e a -> XPure s1 s2 r _ (b | c) * ``` * * Folds over the failed or successful results of this computation to yield * a computation that does not fail, but succeeds with the value of the left * or right function passed to `fold`. * * @category Combinators * @since 1.0.0 */ export const fold = (onFailure: (e: E) => B, onSuccess: (a: A) => C) => ( fa: XPure ) => fold_(fa, onFailure, onSuccess);