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}