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 LRL\dashv R consists of two functors L:CDL:C\to D and R:DCR:D\to C. 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 LRL\dashv R exists, then RR is uniquely recoverable from LL and vice versa. Also, from LRL\dashv R we can’t say anything about left adjoints of LL or right adjoints of RR, they might or might not exist, and they might or might not be equal to RR or LL respectively. So while it’s common to name the functors LL and RR when discussing a single adjoint pair, there is nothing inherent to RR 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 Cat\ccat, 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 [C,D][C,D] of functors between fixed categories CC and DD. How could we possibly draw an arrow from F:CDF:C\to D to G:CDG:C\to D? For all cCc\in C, the objects FcFc and GcGc live in the same category DD, so naturally we can look at morphisms between the two. A possible arrow from FF to GG is a family {αc}c\{\alpha_c\}_c of morphisms αc:FcGc\alpha_c:Fc\to Gc. That alone would be enough to constitute a category structure on [C,D][C,D], but like so often in category theory, we want certain freely constructed entities with matching types to be actually equal. Given a morphism f:cdf:c\to d in CC, we can construct the following square:

Fcα(c)GcFfGfFdα(d)Gd\begin{CD} Fc @> \alpha(c) >> Gc \\ @V Ff VV @VV Gf V \\ Fd @>> \alpha(d) > Gd \end{CD}

In other words, there are two canonical morphisms from FcFc to GdGd constructed just from the presence of ff 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 [C,D][C,D].

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 α\alpha has an inverse transformation β\beta, in the sense of βc\beta_c being a pointwise inverse to αc\alpha_c for all cCc\in C, then β\beta is automatically natural:

Ffβc=βdαdFfβc=βdGfαcβc=βdGf\begin{align*} Ff\circ\beta_c&=\beta_d\circ\alpha_d\circ Ff\circ\beta_c\\ &=\beta_d\circ Gf\circ\alpha_c\circ\beta_c\\ &=\beta_d\circ Gf \end{align*}

Given objects c,dCc,d\in C, the hom-set of morphisms from cc to dd, written homC(c,d)\hom_C(c,d). So homC(,)\hom_C(*,*) is a function from C×CC\times C to Set\cset, 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 Cop×CC^\op\times C rather than C×CC\times C as the domain of the functor, CopC^\op has the same objects as CC, but all arrows are reversed. A morphism (a,b):(c,d)(c,d)(a,b):(c,d)\to(c',d') in this category consists of a:cca:c\to c' in CopC^\op, that is a:cca:c'\to c in CC, and b:ddb:d\to d' in DD. How would that be mapped under the functor homC(,)\hom_C(*,*), that is, how to construct a function from homC(c,d)\hom_C(c,d) to homC(c,d)\hom_C(c',d')? Given a morphism f:cdf:c\to d, we can construct the composition bfa:cdb\circ f\circ a:c'\to d'. Abstracting over ff, this yields a function ba:homC(c,d)homC(c,d)b\circ*\circ a:\hom_C(c,d)\to\hom_C(c',d'), and one can check that it satisfies all requirements to turn homC(,)\hom_C(*,*) into a functor.

At this point, we have all the pieces in place to define adjoint functors. Given L:CDL:C\to D and R:DCR:D\to C as before, we can construct the functor compositions homD(L,):=homD(,)(L×idD)\hom_D(L*,*):=\hom_D(*,*)\circ(L\times\id_D) and homC(,R):=homC(,)(idC×G)\hom_C(*,R*):=\hom_C(*,*)\circ(\id_C\times G), both running from Cop×DC^\op\times D to Set\cset.

LL and RR form an adjoint pair LRL\vdash R, if and only if there is a natural isomorphism

Φ:homD(L,)homC(,R).\Phi:\hom_D(L*,*)\cong\hom_C(*,R*).

For clarity, we can write out the square from before, to see what naturality exactly means here:

homD(Lc,d)Φ(c,d)homC(c,Rd)hom(L,)(ba)hom(,R)(ba)homD(L,d)Φ(c,d)homC(c,Rd)\begin{CD} \hom_D(Lc,d) @> \Phi(c,d) >> \hom_C(c,Rd) \\ @V \hom(L*,*)(b\circ*\circ a) VV @VV \hom(*,R*)(b\circ*\circ a) V \\ \hom_D(L',d') @>> \Phi(c',d') > \hom_C(c',Rd') \end{CD}

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 CC or DD, which act as objects in Set\cset, and appear in the corners of the square, and the hom-sets between them. Interestingly, if two objects in Set\cset 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 Set\cset, in this special case it suffices to check that all homD(Lc,d)\hom_D(Lc,d) and homC(c,Rd)\hom_C(c,Rd) 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 ι:ZR\iota:\zz\to\rr of integers into real numbers. Here, we turn partially (or in this case, totally) ordered sets into categories by assuming exactly one unique arrow xyx\to y whenever xyx\preceq y. For a non-integer number such as π\pi, we can’t directly map it back into Z\zz, the closest maps we get are ceil:RZ\mathsf{ceil}:\rr\to\zz, choosing the smallest integer greater or equal to the input, and floor:RZ\mathsf{floor}:\rr\to\zz, choosing the largest integer smaller or equal to the input. It turns out that these are exactly the left and right adjoints to ι\iota respectively.

Since all arrows in poset categories are unique, as discussed before, checking the adjointness in the case of ceil\mathsf{ceil} simplifies to verifying that homZ(ceil(),)\hom_\zz(\mathsf{ceil}(*),*) is inhabited if and only if homR(,ι())\hom_\rr(*,\iota(*)) is. This condition boils down precisely to ceil(r)zrι(z)=z\mathsf{ceil}(r)\le z\Leftrightarrow r\le\iota(z)=z, which is equivalent to the definition of ceil\mathsf{ceil}. Verifying that floor\mathsf{floor} 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 :GrpSet|*|:\mathsf{Grp}\to\cset. 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 GG and maps it to the base set G|G|, 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 XX some group RxRx such that the set functions from G|G| to XX correspond exactly to the group morphisms from GG to RXRX? This concept is called the free group FXF_X on XX, its elements are all the words over the alphabet {x,x1:xX}\{x,x^{-1}:x\in X\} with no occurences of pairs of inverses like xx1xx^{-1} or x1xx^{-1}x, 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 GG and any set function f:GXf:|G|\to X there is a unique group homomorphism f^:GFX\hat f:G\to F_X extending ff.

For a deeper understanding, let’s briefly revisit invertible functions in Set\cset, it can serve as a blueprint for invertible functors and how adjoints generalize them. A bijection (isomorphism) f:XYf:X\to Y can be defined as an injective and surjective function, or as the existence of g:YXg:Y\to X such that fg=idYfg=\id_Y and gf=idXgf=\id_X. However, there is a third perspective: both functions ff and gg can be seen as representing the same information, just encoded in different ways. Every function f:XYf:X\to Y can be represented by its graph graph(f)\mathsf{graph}(f), defined as the set of pairs (x,f(x)):xX{(x,f(x)):x \in X}. Conversely, every function g:YXg:Y\to X can be represented by its graph in reverse order, which I’ll denote by graphT(g)\mathsf{graph}^T(g), consisting of the pairs (g(y),y):yY{(g(y),y):y\in Y}. Thus, we have an embedding graph:XYP(X×Y)\mathsf{graph}:X^Y\to\mathcal{P}(X \times Y) and another embedding graphT:YXP(X×Y)\mathsf{graph}^T:Y^X\to\mathcal{P}(X\times Y). Within this framework, a function f:XYf:X\to Y 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 CC is just a functor S:CopSetS:C^\op\to\cset, and the category of presheaves, denoted PSh(C)\psh(C), is defined as [Cop,Set][C^\op,\cset]. We can construct a functor from CC to PSh(C)\psh(C) by assigning an object cCc\in C to the presheaf homC(,c)\hom_C(*,c) which maps objects cCc'\in C to the set homC(c,c)\hom_C(c',c). A morphism f:cdf:c\to d 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 yC:CPSh(C)y_C:C\to\psh(C). Conversly, a presheaf SS on CC is called representable if it is isomorphic to yC(c)y_C(c) for some cCc\in C.

The Yoneda Lemma, which we won’t prove here, states that for every presheaf SS on CC and every object cCc'\in C, there is a natural bijection between the sets S(c)S(c') and homPSh(C)(yC(c),S)\hom_{\psh(C)}(y_C(c'),S), or more precisely, a natural isomorphism between the functors SS and homPSh(C)(yC(),S)\hom_{\psh(C)}(y_C(*), S) from CopC^\op to Set\cset. This is quite a lot to digest, but for us, the important case is where SS equals the presheaf yC(c)y_C(c). Here it says that for every cCc'\in C, there is a natural bijection between the set the set yC(c)y_C(c'), that is, the morphisms from cc' to cc, and the set of natural transformations from yC(c)y_C(c') to yC(c)y_C(c). This tells us that yCy_C 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 PSh(C)\psh(C) spanned by the objects yC(c)y_C(c) is isomorphic to CC.

The category of presheaves over CC is in some sense the completion of CC, automatically satisfying nice properties like completeness and cocompleteness, even when CC does not. However, while sometimes compared to the completion of a metric space, the analogy is not perfect. First, there’s no idempotence: PSh(PSh(C))\psh(\psh(C)) typically doesn’t resemble PSh(C)\psh(C), you can repeatedly create new structure by taking presheafs from presheafs. Second, unlike the situation with metric spaces and continuous functions, two functors from PSh(C)\psh(C) to PSh(D)\psh(D) that agree on CC don’t need to be equal or even isomorphic. Third, there’s a directional subtlety absent from the metric setting. The opposite category CopC^\op encodes the same data underlying data with arrows reversed, yet PSh(Cop)\psh(C^\op) can differ significantly from PSh(C)\psh(C). 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 f:X×YZf:X\times Y\to Z into a function f^:XZY\hat f:X\to Z^Y, defined by f^(x)(y):=f(x,y)\hat f(x)(y):=f(x,y). This establishes a bijection between ZX×YZ^{X\times Y} and (ZY)X(Z^Y)^X. The same concept carries over to category theory, where we have an isomorphism between [C×D,E][C \times D, E] and [C,[D,E]][C, [D, E]]. 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 CC and DD (clearly, C×DC\times D is isomorphic to D×CD\times C), one obtains another isomorphism between [C×D,E][C\times D, E] and [D,[C,E]][D, [C, E]].

Recall that for adjoint pairs LRL\vdash R, the functors homD(L,)\hom_D(L*,*) and homC(,R)\hom_C(*,R*) must be isomorphic in [Cop×D,Set][C^\op\times D,\cset], which is also called the category of profunctors from DD to CC, written Prof(D,C)\prof(D,C). By currying, this category is isomorphic both to [Cop,[D,Set]][C^\op,[D,\cset]] and [D,[Cop,Set]][D,[C^\op,\cset]], or written in terms of presheafs, [Cop,PSh(Dop)][C^\op,\psh(D^\op)] and [D,PSh(C)][D,\psh(C)].

We can extend the codomain of any L:CDL:C\to D to PSh(D)\psh(D) via post-composition with yDy_D. This operation yields an embedding of [C,D][C,D] into [C,PSh(D)][C,\psh(D)], and, by uncurrying, also into Prof(C,D)\prof(C,D). Similarly, we can post-compose any R:DCR:D\to C with yCy_C, this yields an object in [D,PSh(C)][D,\psh(C)], but this does uncurry to Prof(D,C)\prof(D,C) and not Prof(C,D)\prof(C,D), so we need a different approach. Taking the opposite functor Rop:DopCopR^\op:D^\op\to C^\op, which contains precisely the same data as RR, post-composing it with yCopy_{C^\op} yields an object in [Dop,PSh(Cop)][D^\op,\psh(C^\op)], which nicely uncurries to Prof(C,D)\prof(C,D). We could of course also use Prof(D,C)\prof(D,C) as common ambient category, by taking the opposite of LL instead of RR, in the end it’s just a matter of taste.

This reveals an interesting perspective. The profunctor category Prof(D,C)\prof(D,C) acts as an ambient category for both, [C,D][C,D] and [D,C][D,C], analogous to how P(X×Y)\mathcal{P}(X\times Y) acts as an ambient set for XYX^Y and YXY^X. For a functor L:CPSh(D)L':C\to\psh(D), there is always a corresponding functor R:DopPSh(Cop)R':D^\op\to\psh(C^\op), due to the isomorphism [C,PSh(D)][Dop,PSh(Cop)][C,\psh(D)]\cong[D^\op,\psh(C^\op)], and vice versa. So also every L:CDL:C\to D has a corresponding “pseudo-adjoint” (not a standard term) R:DopPSh(Cop)R':D^\op\to\psh(C^\op), by using L:=yCLL':=y_C\circ L, but if it doesn’t map DopD^\op neatly into the essential image of yDopy_{D^\op}, that is the extension of the image by isomorphic objects (presheafs), then LL has no right adjoint, and vice versa for R:DCR:D\to C.

In other words, to find a right adjoint to LL, it suffices that for each object dDd\in D, the presheaf homD(L,d)\hom_D(L*,d) is representable in CC. This presheaf is precisely the value of dd under the pseudo-adjoint RR' constructed above. If RdR'd happens to lie in the essential image of the Yoneda embeding yCy_C, then there exists an object RdCRd\in C with

homD(L,d)homC(,Rd).\hom_D(L*,d)\cong\hom_C(*,Rd).

This might seem odd at first because it appears to require naturality only in CC, whereas the definition of adjoint functors demands combined naturality in both CC and DD. The reason for this discrepancy is that we have not fixed any action on morphisms for RR, we only verified the existence of an adjoint by checking locally for representability. The morphisms come straight from the pseudo-adjoint RR', by fullness of the Yoneda embedding, if the presheafs homD(L,d)\hom_D(L*,d) are representable in CC, then any natural transformations between these presheafs, so especially the images of morphisms g:ddg:d\to d' in DD under RR', are automatically representable as well, that means, there is a unique morphism in CC corresponding to the natural transformations yD(g)y_D(g).

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.