you could generalize
I could do, but once I thought that this less-general definition is fine because it has its merit. But thinking again may worth.
Citing README:
Comparison against similar type classes
(…)
-
From index-core: IFunctor
, IMonad
They are endofunctors on the category of type constructors of kind k -> Type
and polymorphic functions t :: forall (x :: k). f x -> g x
.
While any instance of FFunctor
from this package can be faithfully represented as a IFunctor
, some instances can’t be an instance of IFunctor
as is.
Most notably, Free can’t be an instance of IFunctor
directly,
because Free
needs Functor h
to be able to implement fmapI
, the method of IFunctor
.
class IFunctor ff where
fmapI :: (g ~> h) -> (ff g ~> ff h)
There exists a workaround: you can use another representation of Free f
which doesn’t require Functor f
to be a Functor
itself,
for example Program
from operational package.
This package avoids the neccesity of the workaround by admitting the restriction that the parameter of FFunctor
must always be a Functor
.
Therefore, FFunctor
gives up instances which don’t take Functor
parameter, for example, a type constructor F
with kind F :: (Nat -> Type) -> Nat -> Type
.
Saying the same thing quickly, Any FFunctor ff
can be encoded as IFunctor (ff ∘ Coyoneda)
. Many instances can have a more direct IFunctor ff
instance, but some (like Free
) can’t avoid the Coyoneda
indirection.
My another justification of being less general is that a library focusing on a specific structure in detail is no worse than a library for generic things. Anyway, I think the “correct” direction for the ultimate generalization is to have the functor class between arbitrary categories (or higher-categories or …)
One of that specific detail is, like you said, FStrong ff
. It makes sense only for a FFunctor ff
. Not just because of its kind, but also for the fact Day f g
makes sense only for Functor f
and Functor g
. A hypothetical “take-Functor
-and-return-Contravariant
-functor” with kind (Type -> Type) -> Type -> Type
can well be IFunctor
but it wants another class using other tensor products, not FStrong
.
Or I’m just getting too fixated on the first idea I got.