I thought I would share one of my favorite constructions in
Although it's a trivial result in category theory how it
manifests in Haskell is quite lovely.

A Functor in Haskell maps objects and morphism (i.e. functions)
in a subcategory of Hask to objects and morphisms of another
category.

class Functor f where
fmap :: (a -> b) -> f a -> f b


And satisfies the functor laws:

fmap id = id
fmap (a . b) = (fmap a) . (fmap b)


In commutative diagrams we draw objects as points and morphisms
as arrows. In a string diagrams we invert this and draw morphisms
as points and objects as lines.

Functor composition is defined for $F : \mathcal{A} \rightarrow \mathcal{B}$, $G : \mathcal{B} \rightarrow \mathcal{C}$ as $G \circ F : \mathcal{A} \rightarrow \mathcal{C}$, and is drawn with
parallel lines.

newtype FComp f g a = C { unC :: f (g a) }

instance (Functor f, Functor g) => Functor (FComp f g) where
fmap f (C x) = C (fmap (fmap f) x)


Generally the composition of functors $F \circ G$ is written
simply as $FG$. Composition diagrammatically allows us to
collapse adjacent segments in our string diagram.

The identity functor ( $\text{Id}$ ) is the functor that maps
each morphism and object to itself.

newtype Id a = Identity { unId :: a }

instance Functor Id where
fmap f x = Identity (f (unId x))


Composition with the identity functor forms an identity relation:

$$F \circ \text{Id}_B = F \ \text{Id}_A \circ F = F$$

As witnessed by the expressions:

left :: Functor f => FComp f Id a -> f a
left (C a) = fmap unId a

right :: Functor f => f a -> FComp f Id a
right a = C $fmap Identity a  We'll follow the convention to omit the identity functor, and it is shown as a dotted line in subsequent string diagrams. A natural transformation in our context will be a polymorphic function associated with two Haskell functor instances f and g with type signature (Functor f, Functor g) => forall a. f a -> g a. Which could be written with the following type synonym. type Nat f g = forall a. f a -> g a  The identity natural transform mapping a functor$F$to itself is written$1_F$and in Haskell is just (id). The composition of natural transformations follows the associativity laws, shown below: The final interchange law states that we can chase the natural transformations through the functors horizontally or compose natural transformation between functors vertically and still arrive at the same result. $$(\alpha \beta) \circ (\alpha' \beta') = (\alpha \alpha') \circ (\beta \beta')$$ type NatComp f f' g g' = forall a. f' (f a) -> g' (g a) vert :: (Functor f, Functor f', Functor g, Functor g') => Nat f' g' -> Nat f g -> NatComp f f' g g' vert a b x = a (fmap b x) horiz :: (Functor f, Functor f', Functor g, Functor g') => Nat f' g' -> Nat f g -> NatComp f f' g g' horiz a b x = fmap b (a x)  By the interchange law horiz and vert must be interchangable under composition. For natural transformations a, b, a', b' in Haskell we have the equation: (a . b) vert (a' . b') == (a horiz a') . (b horiz b')  A diagram example for a natural transformation$\eta : 1_\mathcal{C}
\rightarrow {FG}$between the identity functor and the composition functor of$FG$would be drawn as: An isomorphism$F \cong G$implies that composition of functors is invertible in that$F G = \text{Id}_C$and$G F =
\text{Id}_D$. An adjoint$F ⊣ G$between a pair of functors$F :
D \rightarrow C$and$G : C \rightarrow D$is a weaker statement that there exists a pair of associated natural transformations$(F, G, \epsilon, \eta)$with: $$\epsilon : FG \rightarrow 1_\mathcal{C} \ \eta : 1_\mathcal{D} \rightarrow FG$$ Such that the following triangle identities hold: $$(\epsilon F) \circ (F \eta) = 1_F \ (G \epsilon) \circ (\eta G) = 1_G$$ These are drawn below: In terms of the categories$C,D$an adjoint is in some sense a "half-isomorphism" or "almost inverse" but some structure is lost in one direction.$\eta$and$\epsilon$are also referred to respectively as the unit and counit. In Haskell we have the following typeclass which unfortunately requires a functional dependency in order for type inferencer to deduce which fmap is to be used: class (Functor f, Functor g) => Adjoint f g | f -> g, g -> f where eta :: a -> g (f a) epsilon :: f (g a) -> a  There are also two other natural transformations ($\phi, \psi$) which together with the adjoint functor pair form an adjunction. The adjunction can be defined in terms of the adjoint pair and this is most convenient definition in Haskell $$\psi \epsilon = 1_F \ \phi \eta = 1_G$$ phi :: Adjoint f g => (f a -> b) -> a -> g b phi f = fmap f . eta psi :: Adjoint f g => (a -> g b) -> f a -> b psi f = epsilon . fmap f  Notably$\phi$and$\psi$form an isomorphism between the set of functions (a -> g b) and (f a -> b) which is the same relation as the above triangle identities. Alternatively$\eta$and$\epsilon$can be expressed in terms of$\phi$and$\psi$. phi eta = id psi epsilon = id  From the Haskell Prelude we have the canonical adjoint namely curry and uncurry: $$\text{curry} \quad ⊣ \quad \text{uncurry}$$ instance Functor ((,) a) where fmap f (x,y) = (x, f y) instance Functor ((->) a) where fmap f g = \x -> f (g x)  Which we can construction an Adjoint instance from these two functor instances: instance Adjoint ((,) a) ((->) a) where eta x y = (y, x) epsilon (y, f) = f y  We can check that the triangle equalities hold for this definition by showing both$(\epsilon F) \circ (F \eta)$and$(G
\epsilon) \circ (\eta G)$reduce to the identity natural transformation ( id ). a0 :: (a -> (b -> c)) -> a -> (b -> c) a0 f = \f -> fmap (epsilon . fmap f) . eta a0 f = fmap (\(y, f) -> g f y) . eta a0 f = \x y -> f x y a1 :: ((a, b) -> c) -> (a,b) -> c a1 f = epsilon . fmap (fmap f . eta) a1 f = epsilon . fmap (\x y -> f (y, x)) a1 f = \(x, y) -> f (x, y)  We know a Monad is an endofunctor$T : C \rightarrow C$with two natural transformations$(T, \mu, \eta)$with the usual laws: $$\mu \circ T \mu = \mu \circ \mu T \ \mu \circ T \eta = \mu \circ \eta T = 1_T \$$ The geometric intuition is that the monad laws are reflected as topological properties of the string diagrams. Both$\mu$and$\eta$exhibit reflection symmetry and that we topologically straighten out$\eta$to yield the identity functor. In Haskell we can normally construct the Monad type class from an Endofunctor and ($\mu, \eta$) or join and return. class (Functor t) => Monad t where eta :: a -> (t a) mu :: (t (t a)) -> (t a) (>>=) :: t a -> (a -> t b) -> t b ma >>= f = mu . fmap f return = eta join = mu  What is not immediately apparent though is that every adjoint pair of functors gives rise to a monad$(T, \mu, \eta)$over a category$C\$ induced by the composition of the functors to give
rise to a endofunctor and natural transformations in terms of the
unit and counit of the underlying adjunction:

\begin{align} T &= G \circ F & : &C \rightarrow C \ \mu &= G \epsilon & : &T^2 \rightarrow T \ \end{align}

class Adjoint f g => Monad f g where
muM :: g (f (g (f a))) -> g (f a)
muM = fmap epsilon

etaM :: a -> g (f a)
etaM = eta

(>>=) :: g (f a) -> (a -> g (f b)) -> g (f b)
x >>= f = muM (fmap (fmap f) x)


The geometric intution for this is clear:

From the Monad we can then construct the Kleisli category in the
usual way.

class (Adjoint f g, Category c) => Kleisli c f g where
idK :: c x (g (f x))
(<=<) :: c y (g (f z)) -> c x (g (f y)) -> c x (g (f z))

instance Monad f g => Kleisli (->) f g where
idK = eta
g <=< f = muM . fmap (fmap g) . f

instance Kleisli c f g => Monoid (c a (g (f a))) where
mempty  = idK
mappend = (<=<)


In retrospect this is trivial, but importantly leads us to the
more important question: Can we recover an adjunction from a