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}