Are all Haskell functors endofunctors?

You may want to clarify whether you’re asking about “functors in Haskell”, or Functors. It’s not always clear what category is being assumed when Category Theory terms are used in Haskell.

But yes, the default assumption is Hask, which is taken to be the category of Haskell types with functions as morphisms. In that case, an endofunctor F on Hask would map any type A to a type F(A) and any function f between two types A and B to a function F(f) between some types F(A) and F(B).

If we then limit ourselves to only those endofunctors which map any type a to a type (f a) where f is a type constructor with kind * -> *, then we can describe the associated map for functions as a higher-order function with type (a -> b) -> (f a -> f b), which is of course the type class called Functor.

However, one can easily imagine well-behaved endofunctors on Hask which can’t be written (directly) as an instance of Functor, such as a functor mapping a type a to Either a t. And while there’s obviously not much sense in a functor from Hask to some other category entirely, it’s reasonable to consider a (contravariant) functor from Hask to Haskop.

Beyond that, instances of Functor necessarily map from the entire category Hask onto some subset of it that, thus, also forms a category. But it’s also reasonable to talk about functors between subsets of Hask. For instance, consider a functor that sends types Maybe a to [a].

You may wish to peruse the category-extras package, which provides some Category Theory-inspired structures embedded within Hask instead of assuming the entirety of it.

Leave a Comment