Skip to main content

fp_library/classes/
ref_functor.rs

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