import type { XPure } from "./model";
import {
FailInstruction,
ModifyInstruction,
PartialInstruction,
SucceedInstruction,
SuspendInstruction,
TotalInstruction
} from "./model";
/**
* ```haskell
* succeed :: a -> XPure s1 s2 _ _ a
* ```
*/
export const succeed = (a: A): XPure =>
new SucceedInstruction(a);
export const total = (thunk: () => A): XPure =>
new TotalInstruction(thunk);
export const fail = (e: E): XPure => new FailInstruction(e);
export const modify = (f: (s: S1) => readonly [S2, A]): XPure =>
new ModifyInstruction(f);
export const suspend = (factory: () => XPure): XPure =>
new SuspendInstruction(factory);
export const sync = (thunk: () => A) => suspend(() => succeed(thunk()));
export const partial_ = (f: () => A, onThrow: (reason: unknown) => E): XPure =>
new PartialInstruction(f, onThrow);
export const partial = (onThrow: (reason: unknown) => E) => (f: () => A) => partial_(f, onThrow);