2.4 KiB
2.4 KiB
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. .
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.
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 controversial1.
- Use of direct/indirect mutable references is, arguably, counter-functional1.
Clone+FnMut
is, generally, nonsensical1.- 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.
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;
}
Copy
-Fn
category functors
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)
}
-
elaborate? ↩︎