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::*;