pub trait Deferrable<'a> {
// Required method
fn defer(f: impl FnOnce() -> Self + 'a) -> Self
where Self: Sized;
}Expand description
A type class for types that can be constructed lazily.
Deferrable is the inverse of Extract: where
Extract forces/extracts the inner value, Deferrable constructs a value
lazily from a thunk. For types whose brand implements Extract (e.g.,
ThunkBrand), extract(defer(|| x)) == x
forms a round-trip. Note that Deferrable is a value-level trait
(implemented by concrete types like Thunk), while Extract is a
brand-level trait (implemented by ThunkBrand).
§Laws
Deferrable instances must satisfy the following law:
- Transparency: The value produced by
defer(|| x)is identical tox. This law does not constrain when evaluation occurs; some implementations may evaluate eagerly.
§Why there is no generic fix
In PureScript, fix :: Lazy l => (l -> l) -> l enables lazy self-reference,
which is essential for tying the knot in recursive values. In Rust, lazy
self-reference requires shared ownership (Rc/Arc) and interior mutability,
which are properties specific to Lazy rather than
all Deferrable types. For example, Thunk is consumed
on evaluation, so self-referential construction is not possible.
The concrete functions rc_lazy_fix and
arc_lazy_fix provide this capability for
Lazy specifically.
Deferrable is for single-threaded deferred construction. For thread-safe
deferred construction with Send closures, use
SendDeferrable.
§Type Parameters
'a: The lifetime of the computation.
§Examples
Transparency law for Thunk:
use fp_library::{
functions::*,
types::*,
};
// Transparency: defer(|| x) is equivalent to x when evaluated.
let x = Thunk::pure(42);
let deferred: Thunk<i32> = defer(|| Thunk::pure(42));
assert_eq!(deferred.evaluate(), x.evaluate());Required Methods§
Sourcefn defer(f: impl FnOnce() -> Self + 'a) -> Selfwhere
Self: Sized,
fn defer(f: impl FnOnce() -> Self + 'a) -> Selfwhere
Self: Sized,
Creates a value from a computation that produces the value.
This function takes a thunk and creates a deferred value that will be computed using the thunk.
§Type Signature
(() -> Self) -> Self
§Parameters
f: A thunk that produces the value.
§Returns
The deferred value.
§Examples
use fp_library::{
functions::*,
types::*,
};
let eval: Thunk<i32> = defer(|| Thunk::pure(42));
assert_eq!(eval.evaluate(), 42);Implementors§
impl<'a, A> Deferrable<'a> for Lazy<'a, A, RcLazyConfig>where
A: Clone + 'a,
§Type Parameters
'a: The lifetime of the computation.A: The type of the computed value.
impl<'a, A, E> Deferrable<'a> for TryLazy<'a, A, E, RcLazyConfig>
§Type Parameters
'a: The lifetime of the computation.A: The type of the computed value.E: The type of the error.
impl<'a, A, E> Deferrable<'a> for TryThunk<'a, A, E>where
A: 'a,
E: 'a,
§Type Parameters
'a: The lifetime of the computation.A: The type of the success value.E: The type of the error value.
impl<'a, A: 'a> Deferrable<'a> for Thunk<'a, A>
§Type Parameters
'a: The lifetime of the computation.A: The type of the value produced by the computation.
impl<A, E> Deferrable<'static> for TryTrampoline<A, E>where
A: 'static,
E: 'static,
§Type Parameters
A: The type of the success value.E: The type of the error value.
impl<A: 'static> Deferrable<'static> for Free<ThunkBrand, A>
§Type Parameters
A: The result type.
impl<A: 'static> Deferrable<'static> for Trampoline<A>
§Type Parameters
A: The type of the value produced by the task.