import type { Lazy } from "@tsplus/stdlib/data/Function" /** * `Eval` is a purely functional description of a computation. * * Note: while for general cases the `Sync` data type is preferrable, * this data type is designed for speed and low allocations, * it is internally used to suspend recursive procedures but can be * useful whenever you need a fast sync computation that cannot fail * and that doesn't require any environment. * * @tsplus type Eval */ export interface Eval { readonly _A: () => A readonly _TypeId: unique symbol } export type EvalInternal = Succeed | FlatMap | Suspend export const EvalSym = Symbol.for("@tsplus/stdlib/io/Eval") export type EvalSym = typeof EvalSym export const _A = Symbol.for("@tsplus/stdlib/io/Eval/A") export type _A = typeof _A /** * @tsplus type Eval.Ops */ export interface EvalOps { $: EvalAspects } export const Eval: EvalOps = { $: {} } /** * @tsplus type Eval.Aspects */ export interface EvalAspects {} /** * @tsplus unify Eval */ export function unifyEval>( self: X ): Eval<[X] extends [Eval] ? AX : never> { return self } export interface Succeed extends Eval {} export class Succeed implements Equals { readonly _tag = "Succeed" readonly [EvalSym]: EvalSym = EvalSym readonly [_A]!: () => A constructor(readonly a: Lazy) {} [Equals.sym](that: unknown) { return this === that } [Hash.sym]() { return Hash.randomCached(this) } } export interface Suspend extends Eval {} export class Suspend implements Equals { readonly _tag = "Suspend" readonly [EvalSym]: EvalSym = EvalSym readonly [_A]!: () => A constructor(readonly f: Lazy>) {} [Equals.sym](that: unknown) { return this === that } [Hash.sym]() { return Hash.randomCached(this) } } export interface FlatMap extends Eval {} export class FlatMap implements Equals { readonly _tag = "FlatMap" readonly [EvalSym]: EvalSym = EvalSym readonly [_A]!: () => A constructor(readonly value: EvalInternal, readonly cont: (a: A) => EvalInternal) {} [Equals.sym](that: unknown) { return this === that } [Hash.sym]() { return Hash.randomCached(this) } } export interface EvalF extends HKT { readonly type: Eval } export declare namespace Eval { export type HKT = EvalF }