98 lines
2.4 KiB
Markdown
98 lines
2.4 KiB
Markdown
# 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)
|
|
}
|
|
```
|