fp_library/typeclasses/
functor.rs

1use crate::{
2	aliases::ArcFn,
3	hkt::{Apply1, Kind1},
4};
5
6/// A typeclass for types that can be mapped over.
7///
8/// A `Functor` represents a context or container that allows functions to be applied
9/// to values within that context without altering the structure of the context itself.
10///
11/// # Laws
12///
13/// Functors must satisfy the following laws:
14/// * Identity: `map(identity) = identity`.
15/// * Composition: `map(f . g) = map(f) . map(g)`.
16pub trait Functor: Kind1 {
17	/// Maps a function over the values in the functor context.
18	///
19	/// # Type Signature
20	///
21	/// `forall f a b. Functor f => (a -> b) -> f a -> f b`
22	///
23	/// # Parameters
24	///
25	/// * `f`: A function to apply to the values within the functor context.
26	/// * `fa`: A functor containing values of type `A`.
27	///
28	/// # Returns
29	///
30	/// A functor containing values of type `B`.
31	fn map<'a, A: 'a, B: 'a>(f: ArcFn<'a, A, B>) -> ArcFn<'a, Apply1<Self, A>, Apply1<Self, B>>;
32}
33
34/// Maps a function over the values in the functor context.
35///
36/// Free function version that dispatches to [the typeclass' associated function][`Functor::map`].
37///
38/// # Type Signature
39///
40/// `forall f a b. Functor f => (a -> b) -> f a -> f b`
41///
42/// # Parameters
43///
44/// * `f`: A function to apply to the values within the functor context.
45/// * `fa`: A functor containing values of type `A`.
46///
47/// # Returns
48///
49/// A functor containing values of type `B`.
50///
51/// # Examples
52///
53/// ```
54/// use fp_library::{brands::OptionBrand, functions::map};
55/// use std::sync::Arc;
56///
57/// assert_eq!(map::<OptionBrand, _, _>(Arc::new(|x: i32| x * 2))(Some(5)), Some(10));
58/// ```
59pub fn map<'a, Brand: Functor + ?Sized, A: 'a, B: 'a>(
60	f: ArcFn<'a, A, B>
61) -> ArcFn<'a, Apply1<Brand, A>, Apply1<Brand, B>> {
62	Brand::map(f)
63}