/** * A representation for a value that may not be available until the current * transaction is closed. */ export class Lazy { constructor(f : () => A) { this.f = f; } private f : () => A; /** * Get the value if available, throwing an exception if not. * In the general case this should only be used in subsequent transactions to * when the Lazy was obtained. */ get() : A { return this.f(); } /** * Map the lazy value according to the specified function, so the returned Lazy reflects * the value of the function applied to the input Lazy's value. * @param f Function to apply to the contained value. It must be referentially transparent. */ map(f : (a : A) => B) { return new Lazy(() => { return f(this.f()); }); } /** * Lift a binary function into lazy values, so the returned Lazy reflects * the value of the function applied to the input Lazys' values. */ lift(b : Lazy, f : (a : A, b : B) => C) : Lazy { return new Lazy(() => { return f(this.f(), b.f()); }); } /** * Lift a ternary function into lazy values, so the returned Lazy reflects * the value of the function applied to the input Lazys' values. */ lift3(b : Lazy, c : Lazy, f : (a : A, b : B, c : C) => D) : Lazy { return new Lazy(() => { return f(this.f(), b.f(), c.f()); }); } /** * Lift a quaternary function into lazy values, so the returned Lazy reflects * the value of the function applied to the input Lazys' values. */ lift4(b : Lazy, c : Lazy, d : Lazy, f : (a : A, b : B, c : C, d : D) => E) : Lazy { return new Lazy(() => { return f(this.f(), b.f(), c.f(), d.f()); }); } }