fp_library/classes/
send_defer.rs

1//! A trait for deferred lazy evaluation with thread-safe thunks.
2//!
3//! This module defines the [`SendDefer`] trait, which extends `Kind!(type Of<'a, A: 'a>: 'a;)`
4//! to support creating deferred values where the thunk is `Send + Sync`.
5//!
6//! ### Examples
7//!
8//! ```
9//! use fp_library::{brands::*, functions::*, types::lazy::*};
10//!
11//! let lazy = send_defer::<LazyBrand<ArcLazyConfig>, _, _>(|| ArcLazy::new(ArcLazyConfig::new_thunk(|_| 42)));
12//! assert_eq!(Lazy::force(&lazy).unwrap(), &42);
13//! ```
14
15use crate::{Apply, kinds::*};
16
17/// A trait for deferred lazy evaluation with thread-safe thunks.
18///
19/// This is similar to `Defer`, but the thunk must be `Send + Sync`.
20pub trait SendDefer: Kind_cdc7cd43dac7585f {
21	/// Creates a deferred value from a thread-safe thunk.
22	///
23	/// ### Type Signature
24	///
25	/// `forall f a. (SendDefer f, Send a, Sync a) => (() -> a) -> f a`
26	///
27	/// ### Type Parameters
28	///
29	/// * `A`: The type of the value.
30	///
31	/// ### Parameters
32	///
33	/// * `thunk`: The function that produces the value.
34	///
35	/// ### Returns
36	///
37	/// A deferred value.
38	///
39	/// ### Examples
40	///
41	/// ```
42	/// use fp_library::{brands::*, functions::*, types::*};
43	///
44	/// let lazy = send_defer::<LazyBrand<ArcLazyConfig>, _, _>(|| ArcLazy::new(ArcLazyConfig::new_thunk(|_| 42)));
45	/// assert_eq!(Lazy::force(&lazy).unwrap(), &42);
46	/// ```
47	fn send_defer<'a, A>(
48		thunk: impl 'a
49		+ Fn() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
50		+ Send
51		+ Sync
52	) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
53	where
54		A: Clone + Send + Sync + 'a;
55}
56
57/// Creates a deferred value from a thread-safe thunk.
58///
59/// Free function version that dispatches to [the type class' associated function][`SendDefer::send_defer`].
60///
61/// ### Type Signature
62///
63/// `forall f a. (SendDefer f, Send a, Sync a) => (() -> a) -> f a`
64///
65/// ### Type Parameters
66///
67/// * `Brand`: The brand of the deferred type.
68/// * `A`: The type of the value.
69/// * `F`: The type of the thunk.
70///
71/// ### Parameters
72///
73/// * `thunk`: The function that produces the value.
74///
75/// ### Returns
76///
77/// A deferred value.
78///
79/// ### Examples
80///
81/// ```
82/// use fp_library::{brands::*, functions::*, types::*};
83///
84/// let lazy = send_defer::<LazyBrand<ArcLazyConfig>, _, _>(|| ArcLazy::new(ArcLazyConfig::new_thunk(|_| 42)));
85/// assert_eq!(Lazy::force(&lazy).unwrap(), &42);
86/// ```
87pub fn send_defer<'a, Brand, A, F>(
88	thunk: F
89) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
90where
91	Brand: SendDefer,
92	A: Clone + Send + Sync + 'a,
93	F: 'a + Fn() -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) + Send + Sync,
94{
95	Brand::send_defer(thunk)
96}