Skip to the content.

Hom functor

When you have objects P and Q in a category C, there are zero or more morphisms from P to Q. A set of these morphisms are called a hom-set and written as C(P, Q). (This is true only when C is locally small, but let’s forget about it now).

Since a hom-set is a set, it consists a category. Each object in this category is a hom-set such as C(P, Q). Let’s call this category D.

If there are R and S in C in addition to P and Q, we have also C(P, R), C(P, S), C(Q, R) and so on in D, but let’s focus on hom-sets whose origin is P such as C(P, P), C(P, Q), C(P, R), C(P, S) now.

Since C and D are categories, there can be functors from C to D. One of these functors maps Q in C to C(P, Q) in D, and maps R in C to C(P, R) in D, and so on. It also maps morphisms from Q to R in C to morphisms from C(P, Q) to C(P, R) in D. This functor is called a hom-functor, and denoted by C(P, -).

If C is a cartesian closed category like Hask, there are exponential objects such as [P, Q] and [P, R] that are isomorphic to C(P, Q) and C(P, R). In this case, a hom-functor maps Q to [P, Q], so is an endo functor. We call this kind of hom-functor an internal hom-functor.

In Haskell, a set of morphisms from P to Q is expressed as an exponential object (or hom-object) P -> Q, and (->) P is an internal hom-functor. (->) P maps Q to P -> Q, and maps morphisms Q -> R to (P -> Q) -> (P -> R) by function composition.

We can have another set of hom-functors by fixing a destination instead of an origin. This functor maps Q in C to C(Q, P), and R to C(R, P), for example, and denoted by C(-, P). As you might’ve expected, this functor is a contravariant functor as oppose to a covariant functor C(P, -).

In Haskell, it’s expressed as Data.Functor.Contravariant.Op and instance of Data.Functor.Contravariant.Contravariant.