Search code examples
haskelltypeclassfunctorcategory-theory

What are the situations when you can/cannot have a Functor instances for a datatype?


Considering a type with kind * -> *, I'm trying to find rules and build intuition for when you can and when you cannot have Functor for this type.

So far the rules that I see are the following:

  1. No Functor instance for the container types that have restrictions on the contained values.

Example: You cannot have a Functor instance for Set because Ord is needed for the contained value

  1. No Functor instance for contravariant data types.

Example:

newtype Contra a = Contra (a -> Int)

Besides this, are there other situations?


Solution

  • In addition to your rules:

    • Must be of kind * -> *
    • No Functor instance for the container types that have restrictions on the contained values.
    • No Functor instance for contravariant data types.

    I would add a few:

    • A natural extension of "not for contravariant types": no Functor instance for invariant data types. e.g. data Iso a b = Iso (a -> b) (b -> a)
    • GADTs often cannot have a Functor instance. For example,

      data Foo a where
          Foo :: Foo Int
      

      Perhaps you would somehow want to lump this into the "only covariant" rule somehow (it's not clear to me what variance this even has), or the "unrestricted container types" rule somehow (GADTs introduce type equalities that are very constraint-like).

    However, keep in mind that these rules apply to Functor only, not to functors in general. I expect any stupid type (of appropriate kind) you can cook up will be a functor on some suitable category closely related to Hask.