fp_library/classes/
defer.rs

1//! A type class for types that can be constructed lazily.
2//!
3//! ### Examples
4//!
5//! ```
6//! use fp_library::{brands::*, classes::*, functions::*, types::*};
7//!
8//! let lazy = defer::<RcLazy<'_, i32>, RcFnBrand>(
9//!     cloneable_fn_new::<RcFnBrand, _, _>(|_| RcLazy::new(RcLazyConfig::new_thunk(|_| 42)))
10//! );
11//! assert_eq!(Lazy::force(&lazy).unwrap(), &42);
12//! ```
13
14use super::CloneableFn;
15
16/// A type class for types that can be constructed lazily.
17pub trait Defer<'a> {
18	/// Creates a value from a computation that produces the value.
19	///
20	/// This function takes a thunk (wrapped in a cloneable function) and creates a deferred value that will be computed using the thunk.
21	///
22	/// ### Type Signature
23	///
24	/// `forall a. Defer d => (() -> d a) -> d a`
25	///
26	/// ### Type Parameters
27	///
28	/// * `FnBrand`: The brand of the cloneable function wrapper.
29	///
30	/// ### Parameters
31	///
32	/// * `f`: A thunk (wrapped in a cloneable function) that produces the value.
33	///
34	/// ### Returns
35	///
36	/// The deferred value.
37	///
38	/// ### Examples
39	///
40	/// ```
41	/// use fp_library::{brands::*, classes::*, functions::*, types::*};
42	///
43	/// let lazy = defer::<RcLazy<'_, i32>, RcFnBrand>(
44	///     cloneable_fn_new::<RcFnBrand, _, _>(|_| RcLazy::new(RcLazyConfig::new_thunk(|_| 42)))
45	/// );
46	/// assert_eq!(Lazy::force(&lazy).unwrap(), &42);
47	/// ```
48	fn defer<FnBrand: 'a + CloneableFn>(f: <FnBrand as CloneableFn>::Of<'a, (), Self>) -> Self
49	where
50		Self: Sized;
51}
52
53/// Creates a value from a computation that produces the value.
54///
55/// Free function version that dispatches to [the type class' associated function][`Defer::defer`].
56///
57/// ### Type Signature
58///
59/// `forall a. Defer d => (() -> d a) -> d a`
60///
61/// ### Type Parameters
62///
63/// * `D`: The type of the deferred value.
64/// * `FnBrand`: The brand of the cloneable function wrapper.
65///
66/// ### Parameters
67///
68/// * `f`: A thunk (wrapped in a cloneable function) that produces the value.
69///
70/// ### Returns
71///
72/// The deferred value.
73///
74/// ### Examples
75///
76/// ```
77/// use fp_library::{brands::*, classes::*, functions::*, types::*};
78///
79/// let lazy = defer::<RcLazy<'_, i32>, RcFnBrand>(
80///     cloneable_fn_new::<RcFnBrand, _, _>(|_| RcLazy::new(RcLazyConfig::new_thunk(|_| 42)))
81/// );
82/// assert_eq!(Lazy::force(&lazy).unwrap(), &42);
83/// ```
84pub fn defer<'a, D, FnBrand>(f: <FnBrand as CloneableFn>::Of<'a, (), D>) -> D
85where
86	D: Defer<'a>,
87	FnBrand: 'a + CloneableFn,
88{
89	D::defer::<FnBrand>(f)
90}