Here is one way one might implement a categorical Functor (
https://www.reddit.com/r/haskell/comments/eoo16m/base_catego...).
A function S -> T maps a S(ource) type to a T(arget) type, like FunctorOf (-S>) (-T>) does between the source category (-S>) and target category (-T>)
type Functor :: forall (s :: Type) (t :: Type). (s -> t) -> Constraint
class (Category (Src f), Category (Tgt f)) => Functor (f :: s -> t) where
type Src (f :: s -> t) :: Cat s
type Tgt (f :: s -> t) :: Cat t
fmap :: Src f a1 a2 -> Tgt f (f a1) (f a2)
type FunctorOf :: forall (s :: Type) (t :: Type). Cat s -> Cat t -> (s -> t) -> Constraint
type FunctorOf src tgt f = (Functor f, Src f ~ src, Tgt f ~ tgt)
The usual endofunctor
type EndofunctorOf :: forall (ob :: Type). Cat ob -> (ob -> ob) -> Constraint
type EndofunctorOf @ob cat f = FuntorOf @ob @ob cat cat f
we have in Haskell can be defined as FunctorOf @Type @Type (->) (->), or
type OldFunctor :: (Type -> Type) -> Constraint
type OldFunctor f = EndofunctorOf @Type (->) f