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}