# Atlernatives to `Functor` trait ## `_`-`FnOnce` category functors (current) Copied for reference. All following examples are in the same `Functor`-`Applicative`-`Monad` format without extra (sub)traits like `WeakFunctor`, `Pure`, `ApplicativeLA2`, etc. . ```rust trait Functor { type F<'a, A: 'a>: 'a where Self: 'a; fn fmap<'a, A: 'a, B: 'a>( f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>, ) -> Self::F<'a, B> where Self: 'a; } fn fmap<'a, T: 'a + Functor, A: 'a, B: 'a>( f: impl 'a + FnOnce(A) -> B, ) -> impl FnOnce(T::F<'a, A>) -> T::F<'a, B> { |fa| T::fmap(f, fa) } ``` ## `Clone`-`Fn` category functors This is probably the closest representation to what Haskell views as a category of its types. ```rust trait Functor: Clone { type F<'a, A: 'a + Clone>: 'a + Clone where Self: 'a; fn fmap<'a, A: 'a + Clone, B: 'a + Clone>( f: impl 'a + Clone + Fn(A) -> B, fa: Self::F<'a, A>, ) -> Self::F<'a, B> where Self: 'a; } fn fmap<'a, T: 'a + Functor, A: 'a + Clone, B: 'a + Clone>( f: impl 'a + Clone + Fn(A) -> B, ) -> impl 'a + Clone + Fn(T::F<'a, A>) -> T::F<'a, B> { move |fa| T::fmap(f.clone(), fa) } ``` ## `Clone`-`FnMut` category functors We view use of `FnMut` for category's morphisms as somewhat controversial[^e]. * Use of direct/indirect mutable references is, arguably, counter-functional[^e]. * `Clone+FnMut` is, generally, nonsensical[^e]. * Due to that, morphisms category isn't a subcategory, so can't be wrapped. * Not being to wrap morphisms makes implementation of one specific `Applicative` method, sequential application (`<*>` in Haskell, `seq` in RADN) *difficult*. ```rust trait Functor: Clone { type F<'a, A: 'a + Clone>: 'a + Clone where Self: 'a; fn fmap<'a, A: 'a + Clone, B: 'a + Clone>( f: impl 'a + FnMut(A) -> B, fa: Self::F<'a, A>, ) -> Self::F<'a, B> where Self: 'a; } ``` [^e]: elaborate? ## `Copy`-`Fn` category functors ```rust trait Functor: Copy { type F<'a, A: 'a + Copy>: 'a + Copy where Self: 'a; fn fmap<'a, A: 'a + Copy, B: 'a + Copy>( f: impl 'a + Copy + Fn(A) -> B, fa: Self::F<'a, A>, ) -> Self::F<'a, B> where Self: 'a; } fn fmap<'a, T: 'a + Functor, A: 'a + Copy, B: 'a + Copy>( f: impl 'a + Copy + Fn(A) -> B, ) -> impl 'a + Copy + Fn(T::F<'a, A>) -> T::F<'a, B> { move |fa| T::fmap(f, fa) } ```