Skip to main content

fp_library/classes/
send_deferrable.rs

1//! Deferred lazy evaluation using thread-safe thunks.
2//!
3//! ### Examples
4//!
5//! ```
6//! use fp_library::{brands::*, functions::*, types::*};
7//!
8//! let memo: ArcLazy<i32> = send_defer(|| ArcLazy::new(|| 42));
9//! assert_eq!(*memo.evaluate(), 42);
10//! ```
11
12use fp_macros::doc_params;
13use fp_macros::doc_type_params;
14use fp_macros::hm_signature;
15
16/// A trait for deferred lazy evaluation with thread-safe thunks.
17///
18/// This is similar to [`Deferrable`](crate::classes::Deferrable), but the thunk must be `Send + Sync`.
19pub trait SendDeferrable<'a> {
20	/// Creates a deferred value from a thread-safe thunk.
21	///
22	/// ### Type Signature
23	///
24	#[hm_signature(SendDeferrable)]
25	///
26	/// ### Type Parameters
27	///
28	#[doc_type_params("The type of the thunk.")]
29	///
30	/// ### Parameters
31	///
32	#[doc_params("The function that produces the value.")]
33	///
34	/// ### Returns
35	///
36	/// A deferred value.
37	///
38	/// ### Examples
39	///
40	/// ```
41	/// use fp_library::{brands::*, functions::*, types::*};
42	///
43	/// let memo: ArcLazy<i32> = send_defer(|| ArcLazy::new(|| 42));
44	/// assert_eq!(*memo.evaluate(), 42);
45	/// ```
46	fn send_defer<F>(f: F) -> Self
47	where
48		F: FnOnce() -> Self + Send + Sync + 'a,
49		Self: Sized;
50}
51
52/// Creates a deferred value from a thread-safe thunk.
53///
54/// Free function version that dispatches to [the type class' associated function][`SendDeferrable::send_defer`].
55///
56/// ### Type Signature
57///
58#[hm_signature(SendDeferrable)]
59///
60/// ### Type Parameters
61///
62#[doc_type_params(
63	"The lifetime of the computation",
64	"The type of the deferred value.",
65	"The type of the thunk."
66)]
67///
68/// ### Parameters
69///
70#[doc_params("The function that produces the value.")]
71///
72/// ### Returns
73///
74/// A deferred value.
75///
76/// ### Examples
77///
78/// ```
79/// use fp_library::{brands::*, functions::*, types::*};
80///
81/// let memo: ArcLazy<i32> = send_defer(|| ArcLazy::new(|| 42));
82/// assert_eq!(*memo.evaluate(), 42);
83/// ```
84pub fn send_defer<'a, D, F>(f: F) -> D
85where
86	D: SendDeferrable<'a>,
87	F: FnOnce() -> D + Send + Sync + 'a,
88{
89	D::send_defer(f)
90}