Adjoint Functors
I struggled for some time with the concept of adjoint functors. Even before writing down the definition, I find their very type signature somewhat unusual. An adjoint pair consists of two functors and . They generalize isomorphisms between categories, in that the inverse to an invertible functor is both, its left and right adjoint. But unlike other generalizations, like left-inverses or right-inverses, they are unique (up to natural isomorphism), that means, if the adjoint pair exists, then is uniquely recoverable from and vice versa. Also, from we can’t say anything about left adjoints of or right adjoints of , they might or might not exist, and they might or might not be equal to or respectively. So while it’s common to name the functors and when discussing a single adjoint pair, there is nothing inherent to making it a right adjoint, it could just as well be the left adjoint to another functor, and vice versa.
Before defining adjoint functors, we need to establish some concepts. First, can functors be meaningfully isomorphic? Do they live in a category themselves? Well, in the category , functors appear as morphisms between categories, but if we want to talk about functors being isomorphic to each other, we should instead consider a category where functors are objects and morphisms between them are something else. Here it makes sense to consider not arbitrary functors but start with the set of functors between fixed categories and . How could we possibly draw an arrow from to ? For all , the objects and live in the same category , so naturally we can look at morphisms between the two. A possible arrow from to is a family of morphisms . That alone would be enough to constitute a category structure on , but like so often in category theory, we want certain freely constructed entities with matching types to be actually equal. Given a morphism in , we can construct the following square:
In other words, there are two canonical morphisms from to constructed just from the presence of without any further assumptions, so it would be natural to ask for equality between these two, or in other words, the square to commute. That is exactly the definition of a natural transformation between functors and it’s the standard categorical structure on .
If all arrows in the category are unique, so hom-sets are empty or singletons, then we clearly don’t need to check for the naturality condition.
Further, a natural isomorphism is a just natural transformation with an inverse. If has an inverse transformation , in the sense of being a pointwise inverse to for all , then is automatically natural:
Given objects , the hom-set of morphisms from to , written . So is a function from to , it takes a pair of objects and returns the hom-set between these objects, and we want to turn this into a functor. This works best if we choose rather than as the domain of the functor, has the same objects as , but all arrows are reversed. A morphism in this category consists of in , that is in , and in . How would that be mapped under the functor , that is, how to construct a function from to ? Given a morphism , we can construct the composition . Abstracting over , this yields a function , and one can check that it satisfies all requirements to turn into a functor.
At this point, we have all the pieces in place to define adjoint functors. Given and as before, we can construct the functor compositions and , both running from to .
and form an adjoint pair , if and only if there is a natural isomorphism
For clarity, we can write out the square from before, to see what naturality exactly means here:
We said before that we don’t need to check for naturality if the hom-sets are empty or singletons. In the naturality square above, however, we need to distinguish between two levels of hom-sets, the hom-sets between elements in or , which act as objects in , and appear in the corners of the square, and the hom-sets between them. Interestingly, if two objects in are empty or singletons, then the set of functions between them is necessarily empty or a singleton as well. As a result, when verifying adjoint functors in a category where all hom-sets are empty or singletons, we don’t need to check for naturality explicitly. Furthermore, since we talk about isomorphism in , in this special case it suffices to check that all and agree in their inhabitedness, that is, that they are either both empty or both singletons, as can be seen in the next example.
Adjoint functors are sometimes motivated as approximate inverses, which approximate the possibly non-existing inverse to a functor from above (left adjoint) or below (right adjoint), where above and below is kept vague here. An example illustrating this point is the embedding of integers into real numbers. Here, we turn partially (or in this case, totally) ordered sets into categories by assuming exactly one unique arrow whenever . For a non-integer number such as , we can’t directly map it back into , the closest maps we get are , choosing the smallest integer greater or equal to the input, and , choosing the largest integer smaller or equal to the input. It turns out that these are exactly the left and right adjoints to respectively.
Since all arrows in poset categories are unique, as discussed before, checking the adjointness in the case of simplifies to verifying that is inhabited if and only if is. This condition boils down precisely to , which is equivalent to the definition of . Verifying that is the right adjoint works similarly.
Another, more typical, example of adjoints is the free group functor, which is the right adjoint to the forgetful functor . Unfortunately, this one only has only one adjoint, so we can’t see the dual approximation from two sides.
The forgetful functor takes a group and maps it to the base set , forgetting all the group structure. The question for a right adjoint then is, can we simulate all the arrows from base sets to other sets within the category of groups? Can we find for each set some group such that the set functions from to correspond exactly to the group morphisms from to ? This concept is called the free group on , its elements are all the words over the alphabet with no occurences of pairs of inverses like or , and the multiplication is just concatenation of words with deletion of possibly newly created pairs of inverses afterwards. The neutral element is the empty word. This group has the special property that for every group and any set function there is a unique group homomorphism extending .
For a deeper understanding, let’s briefly revisit invertible functions in , it can serve as a blueprint for invertible functors and how adjoints generalize them. A bijection (isomorphism) can be defined as an injective and surjective function, or as the existence of such that and . However, there is a third perspective: both functions and can be seen as representing the same information, just encoded in different ways. Every function can be represented by its graph , defined as the set of pairs . Conversely, every function can be represented by its graph in reverse order, which I’ll denote by , consisting of the pairs . Thus, we have an embedding and another embedding . Within this framework, a function is invertible precisely when its graph lies in the intersection of these two embeddings. We will see that there is a similar framework for categories, aiding with the understanding of adjoint functors. But before we can explore this further, we need to build up some machinery.
A so-called presheaf on is just a functor , and the category of presheaves, denoted , is defined as . We can construct a functor from to by assigning an object to the presheaf which maps objects to the set . A morphism acts then on these hom-sets via post-composition. We’ll shortly see that this is actually an embedding, and it’s called the Yoneda embedding functor . Conversly, a presheaf on is called representable if it is isomorphic to for some .
The Yoneda Lemma, which we won’t prove here, states that for every presheaf on and every object , there is a natural bijection between the sets and , or more precisely, a natural isomorphism between the functors and from to . This is quite a lot to digest, but for us, the important case is where equals the presheaf . Here it says that for every , there is a natural bijection between the set the set , that is, the morphisms from to , and the set of natural transformations from to . This tells us that is indeed an embedding, that is, a functor injective on objects and bijective on hom-sets. Another way of looking at it’s that the full subcategory of spanned by the objects is isomorphic to .
The category of presheaves over is in some sense the completion of , automatically satisfying nice properties like completeness and cocompleteness, even when does not. However, while sometimes compared to the completion of a metric space, the analogy is not perfect. First, there’s no idempotence: typically doesn’t resemble , you can repeatedly create new structure by taking presheafs from presheafs. Second, unlike the situation with metric spaces and continuous functions, two functors from to that agree on don’t need to be equal or even isomorphic. Third, there’s a directional subtlety absent from the metric setting. The opposite category encodes the same data underlying data with arrows reversed, yet can differ significantly from . This provides two different “completions” from the same starting point, a phenomenon with no analogue for metric spaces.
In set theory, currying refers to the process of transforming a function into a function , defined by . This establishes a bijection between and . The same concept carries over to category theory, where we have an isomorphism between and . At the level of objects, this correspondence is entirely analogous to the set-theoretic case, and at the level of morphisms, it extends naturally. By swapping and (clearly, is isomorphic to ), one obtains another isomorphism between and .
Recall that for adjoint pairs , the functors and must be isomorphic in , which is also called the category of profunctors from to , written . By currying, this category is isomorphic both to and , or written in terms of presheafs, and .
We can extend the codomain of any to via post-composition with . This operation yields an embedding of into , and, by uncurrying, also into . Similarly, we can post-compose any with , this yields an object in , but this does uncurry to and not , so we need a different approach. Taking the opposite functor , which contains precisely the same data as , post-composing it with yields an object in , which nicely uncurries to . We could of course also use as common ambient category, by taking the opposite of instead of , in the end it’s just a matter of taste.
This reveals an interesting perspective. The profunctor category acts as an ambient category for both, and , analogous to how acts as an ambient set for and . For a functor , there is always a corresponding functor , due to the isomorphism , and vice versa. So also every has a corresponding “pseudo-adjoint” (not a standard term) , by using , but if it doesn’t map neatly into the essential image of , that is the extension of the image by isomorphic objects (presheafs), then has no right adjoint, and vice versa for .
In other words, to find a right adjoint to , it suffices that for each object , the presheaf is representable in . This presheaf is precisely the value of under the pseudo-adjoint constructed above. If happens to lie in the essential image of the Yoneda embeding , then there exists an object with
This might seem odd at first because it appears to require naturality only in , whereas the definition of adjoint functors demands combined naturality in both and . The reason for this discrepancy is that we have not fixed any action on morphisms for , we only verified the existence of an adjoint by checking locally for representability. The morphisms come straight from the pseudo-adjoint , by fullness of the Yoneda embedding, if the presheafs are representable in , then any natural transformations between these presheafs, so especially the images of morphisms in under , are automatically representable as well, that means, there is a unique morphism in corresponding to the natural transformations .
So to summarize, in order to verify adjointness of a given pair of functors, hom-set bijections must be established and naturality checked in both variables. But to verify the existence of an adjoint to a given functor, it suffices to check locally, for each object, whether the corresponding Yoneda embedding is representable.