Skip to main content

fp_library/classes/
deferrable.rs

1//! Types that can be constructed lazily from a computation.
2//!
3//! ### Examples
4//!
5//! ```
6//! use fp_library::{
7//! 	brands::*,
8//! 	functions::*,
9//! 	types::*,
10//! };
11//!
12//! let eval: Thunk<i32> = defer(|| Thunk::new(|| 42));
13//! assert_eq!(eval.evaluate(), 42);
14//! ```
15
16#[fp_macros::document_module]
17mod inner {
18	use fp_macros::*;
19	/// A type class for types that can be constructed lazily.
20	#[document_type_parameters("The lifetime of the computation.")]
21	pub trait Deferrable<'a> {
22		/// Creates a value from a computation that produces the value.
23		///
24		/// This function takes a thunk and creates a deferred value that will be computed using the thunk.
25		#[document_signature]
26		///
27		#[document_parameters("A thunk that produces the value.")]
28		///
29		#[document_returns("The deferred value.")]
30		#[document_examples]
31		///
32		/// ```
33		/// use fp_library::{
34		/// 	brands::*,
35		/// 	functions::*,
36		/// 	types::*,
37		/// };
38		///
39		/// let eval: Thunk<i32> = defer(|| Thunk::new(|| 42));
40		/// assert_eq!(eval.evaluate(), 42);
41		/// ```
42		fn defer(f: impl FnOnce() -> Self + 'a) -> Self
43		where
44			Self: Sized;
45	}
46
47	/// Creates a value from a computation that produces the value.
48	///
49	/// Free function version that dispatches to [the type class' associated function][`Deferrable::defer`].
50	#[document_signature]
51	///
52	#[document_type_parameters(
53		"The lifetime of the computation",
54		"The type of the deferred value."
55	)]
56	///
57	#[document_parameters("A thunk that produces the value.")]
58	///
59	#[document_returns("The deferred value.")]
60	#[document_examples]
61	///
62	/// ```
63	/// use fp_library::{
64	/// 	brands::*,
65	/// 	functions::*,
66	/// 	types::*,
67	/// };
68	///
69	/// let eval: Thunk<i32> = defer(|| Thunk::new(|| 42));
70	/// assert_eq!(eval.evaluate(), 42);
71	/// ```
72	pub fn defer<'a, D: Deferrable<'a>>(f: impl FnOnce() -> D + 'a) -> D {
73		D::defer(f)
74	}
75}
76
77pub use inner::*;