rspace_traits/
functor.rs

1/*
2    Appellation: hkt <module>
3    Contrib: @FL03
4*/
5
6#[deprecated(
7    since = "0.0.7",
8    note = "The `Functor` trait has been renamed to `MapTo` and `MapInto` for better clarity."
9)]
10/// The [`Functor`] trait describes an interface for a higher-kinded type that can be mapped
11/// over. The trait is parameterized over a function `F` and a target type `T`, allowing for
12/// granular control over the mapping process itself, relying on associated types like
13/// `Cont<U>` to define the resulting container type after the mapping operation and the
14/// `Elem` type to specify the type of elements contained within the functor _**before**_
15/// the mapping operation is applied. Moreover, the `apply` method takes ownership of the
16/// functor allowing for distinct implementations for referenced, mutabled, and owned
17/// instances.
18pub trait Functor<F, T>
19where
20    F: FnOnce(Self::Elem) -> T,
21{
22    type Cont<U>: ?Sized;
23    type Elem;
24
25    fn apply(self, f: F) -> Self::Cont<T>;
26}
27
28// pub trait Applicative<T>: Functor<T> {
29//     fn pure(value: T) -> Self::Cont<T>;
30// }
31
32// pub trait Monad<T>: Applicative<T> {
33//     fn flat_map<F, U>(&self, f: F) -> Self::Cont<U>
34//     where
35//         F: Fn(&mut T, &T) -> Self::Cont<U>;
36// }
37
38/*
39 *************  Implementations  *************
40*/
41#[allow(deprecated)]
42impl<U, V, F> Functor<F, V> for Option<U>
43where
44    F: FnOnce(U) -> V,
45{
46    type Cont<T> = Option<T>;
47    type Elem = U;
48
49    fn apply(self, f: F) -> Self::Cont<V> {
50        self.map(f)
51    }
52}
53
54#[allow(deprecated)]
55impl<'a, U, V, F> Functor<F, V> for &'a Option<U>
56where
57    F: FnOnce(&U) -> V,
58{
59    type Cont<T> = Option<T>;
60    type Elem = &'a U;
61
62    fn apply(self, f: F) -> Self::Cont<V> {
63        self.as_ref().map(f)
64    }
65}
66
67#[allow(deprecated)]
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn test_option() {
74        fn sample(input: u8) -> f32 {
75            input as f32 + 1.25
76        }
77        assert_eq! {
78            Some(42u8).apply(sample),
79            Some(43.25f32)
80        }
81    }
82}