Skip to main content

fp_library/classes/
ref_functor.rs

1//! Types that can be mapped over by receiving or returning references to their contents.
2//!
3//! ### Examples
4//!
5//! ```
6//! use fp_library::{brands::*, functions::*, types::*};
7//!
8//! let memo = Lazy::<_, RcLazyConfig>::new(|| 10);
9//! let mapped = ref_map::<LazyBrand<RcLazyConfig>, _, _, _>(
10//!     |x: &i32| *x * 2,
11//!     memo
12//! );
13//! assert_eq!(*mapped.evaluate(), 20);
14//! ```
15
16use crate::{Apply, kinds::*};
17use fp_macros::doc_params;
18use fp_macros::doc_type_params;
19use fp_macros::hm_signature;
20
21/// A type class for types that can be mapped over, returning references.
22///
23/// This is a variant of `Functor` for types where `map` receives/returns references.
24/// This is required for types like `Lazy` where `get()` returns `&A`, not `A`.
25pub trait RefFunctor: Kind_cdc7cd43dac7585f {
26	/// Maps a function over the values in the functor context, where the function takes a reference.
27	///
28	/// ### Type Signature
29	///
30	#[hm_signature(RefFunctor)]
31	///
32	/// ### Type Parameters
33	///
34	#[doc_type_params(
35		"The lifetime of the values.",
36		"The type of the value(s) inside the functor.",
37		"The type of the result(s) of applying the function.",
38		"The type of the function to apply."
39	)]
40	///
41	/// ### Parameters
42	///
43	#[doc_params(
44		"The function to apply to the value(s) inside the functor.",
45		"The functor instance containing the value(s)."
46	)]
47	///
48	/// ### Returns
49	///
50	/// A new functor instance containing the result(s) of applying the function.
51	///
52	/// ### Examples
53	///
54	/// ```
55	/// use fp_library::{brands::*, classes::*, types::*};
56	///
57	/// let memo = Lazy::<_, RcLazyConfig>::new(|| 10);
58	/// let mapped = LazyBrand::<RcLazyConfig>::ref_map(
59	///     |x: &i32| *x * 2,
60	///     memo
61	/// );
62	/// assert_eq!(*mapped.evaluate(), 20);
63	/// ```
64	fn ref_map<'a, A: 'a, B: 'a, Func>(
65		func: Func,
66		fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
67	) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
68	where
69		Func: FnOnce(&A) -> B + 'a;
70}
71
72/// Maps a function over the values in the functor context, where the function takes a reference.
73///
74/// Free function version that dispatches to [the type class' associated function][`RefFunctor::ref_map`].
75///
76/// ### Type Signature
77///
78#[hm_signature(RefFunctor)]
79///
80/// ### Type Parameters
81///
82#[doc_type_params(
83	"The lifetime of the values.",
84	"The brand of the functor.",
85	"The type of the value(s) inside the functor.",
86	"The type of the result(s) of applying the function.",
87	"The type of the function to apply."
88)]
89///
90/// ### Parameters
91///
92#[doc_params(
93	"The function to apply to the value(s) inside the functor.",
94	"The functor instance containing the value(s)."
95)]
96///
97/// ### Returns
98///
99/// A new functor instance containing the result(s) of applying the function.
100///
101/// ### Examples
102///
103/// ```
104/// use fp_library::{brands::*, functions::*, types::*};
105///
106/// let memo = Lazy::<_, RcLazyConfig>::new(|| 10);
107/// let mapped = ref_map::<LazyBrand<RcLazyConfig>, _, _, _>(
108///     |x: &i32| *x * 2,
109///     memo
110/// );
111/// assert_eq!(*mapped.evaluate(), 20);
112/// ```
113pub fn ref_map<'a, Brand: RefFunctor, A: 'a, B: 'a, Func>(
114	func: Func,
115	fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
116) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
117where
118	Func: FnOnce(&A) -> B + 'a,
119{
120	Brand::ref_map::<A, B, Func>(func, fa)
121}