1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Functors in Rust

#![warn(missing_docs)]

mod impls;
#[cfg(test)]
mod tests;

mod sealed {
    pub trait Identity<T> {}
    impl<T> Identity<T> for T {}
}

/// Trait `Identity<T>` is implemented for all `T: Sized`
/// and allows conversion between `Self` and `T`
pub trait Identity<T>: Sized + sealed::Identity<T> {
    /// Convert from `T` into `Self` (no-op)
    fn from_same(this: T) -> Self;
    /// Convert from `Self` into `T` (no-op)
    fn into_same(self) -> T;
}

impl<T> Identity<T> for T
where
    T: sealed::Identity<T>,
{
    fn from_same(this: T) -> Self {
        this
    }
    fn into_same(self) -> T {
        self
    }
}

/// A generic type (e.g. `Vec<A>`) whose inner type can be mapped over
/// (e.g. to `Vec<B>`)
///
/// Type parameter `B` specifies the new inner type after the [`fmap`]
/// operation.
///
/// [`fmap`]: Self::fmap
pub trait Functor<'a, B>
where
    Self: Identity<Self::Mapped<'a, Self::Inner>>,
    B: 'a,
{
    /// Inner type (e.g. `Inner = A` for `Vec<A>`)
    type Inner: 'a;

    /// `Self` with inner type mapped to a different type
    ///
    /// For example,
    /// `<Vec<A> as Functor<'a, B>>::Mapped<'b, C> = Vec<C>`.
    /// It is required that `T::Mapped<'a, T::Inner> = T` (which is
    /// ensured by the compiler).
    type Mapped<'b, C>
    where
        'a: 'b,
        C: 'a;

    /// Replaces inner type and value by applying a mapping function
    fn fmap<'b, F>(self, f: F) -> Self::Mapped<'b, B>
    where
        'a: 'b,
        F: 'b + Fn(Self::Inner) -> B;

    /// Specialized variant of [`fmap`] where the [inner type] isn't
    /// changed
    ///
    /// Opposed to [`fmap`], this method returns `Self` instead of
    /// [`Self::Mapped<B>`], which can help reducing unnecessary trait
    /// bounds.
    /// Its default implementation may be overriden where a more
    /// efficient implementation is available when [`Functor<B>::Inner`]
    /// and `B` are the same types.
    ///
    /// [`fmap`]: Functor::fmap
    /// [inner type]: Self::Inner
    fn fmap_same<F>(self, f: F) -> Self
    where
        Self: FunctorSelf<'a, B>,
        F: 'a + Fn(Self::Inner) -> Self::Inner,
    {
        self.fmap_same_default_impl(f)
    }
}

/// Helper trait to convert between [`<T as Functor>::Mapped`] and `T`
///
/// [`<T as Functor>::Mapped`]: Functor::Mapped
pub trait FunctorSelf<'a, A>: Functor<'a, A>
where
    A: 'a,
{
    /// Convert from [`Functor::Mapped<A>`] into `Self` (no-op)
    fn from_mapped(x: Self::Mapped<'a, A>) -> Self;
    /// Convert from [`Self`] into [`Functor::Mapped<A>`] (no-op)
    fn into_mapped(self) -> Self::Mapped<'a, A>;
    /// Wrapper around [`Functor::fmap`], which converts the return
    /// value into `Self` (no-op conversion)
    ///
    /// This method is the default implementation for
    /// [`Functor::fmap_same`], which may be overridden when
    /// implementing the [`Functor`] trait.
    fn fmap_same_default_impl<F>(self, f: F) -> Self
    where
        F: 'a + Fn(Self::Inner) -> Self::Inner;
}

impl<'a, T, A> FunctorSelf<'a, A> for T
where
    A: 'a,
    T: Functor<'a, A, Inner = A>,
{
    fn from_mapped(mapped: Self::Mapped<'a, A>) -> Self {
        Self::from_same(mapped)
    }
    fn into_mapped(self) -> Self::Mapped<'a, A> {
        self.into_same()
    }
    fn fmap_same_default_impl<F>(self, f: F) -> Self
    where
        F: 'a + Fn(A) -> A,
    {
        Self::from_mapped(self.fmap(f))
    }
}