Previously: Kan extensions in Haskell.
In a double category that is also a proarrow equipment, we have the ability to bend arrows. In particular, in the definition of the counit of the right Kan extension:
we can bend the vertical arrow, replacing it with its horizontal conjoint
. In a profunctor equipment, this is just a representable profunctor
.
A natural generalization is to replace this representable with a general profunctor. This way we get a definition of a right Kan extension along a profunctor .
In a more general setting of a double category, the counit of the right Kan extension is a 2-cell:
The universal condition can be similarly generalized by bending the arrows.
However, the universal condition for pointwise right Kan extensions is stronger. It involves an additional horizontal 1-cell . It states that any 2-cell
of the shape below can be uniquely factorized through the counit
:
Right Kan extensions in Haskell
In Haskell, the right Kan extension of a functor d along a profunctor j can be written as a data type:
newtype Ran j d a = Ran (forall x . j a x -> d x)
This is a direct translation of the categorical formula that uses an end:
Compare this with the earlier implementation of the Kan extension, in which j was a functor:
newtype Ran j d a = Ran (forall x . (a -> j x) -> d x)
The counit is a 2-cell from j to the identity profunctor (->):
epsilon :: (Profunctor j, Functor d) => Cell (Ran j d) d j (->)epsilon jab (Ran ran) = ran jab
The 2-cell Phi goes from the profunctor composition of j and h to the identity profunctor:
type Phi s d j h = Cell s d (Procompose j h) (->)
The factorization cell Phi' goes from h to identity:
type Phi' s d j h = Cell s (Ran j d) h (->)
For any Phi, we can find the corresponding Phi':
rightAdj :: (Profunctor j, Profunctor h, Functor d, Functor s) => Phi s d j h -> Phi' s d j hrightAdj phi hac sa = Ran (\ jcb -> phi (Procompose jcb hac) sa)
This function replaces the right adjoint used in the traditional definition of a Kan extension.
The result satisfies the factorization property:
factor :: (Profunctor j, Profunctor h, Functor d, Functor s) => Phi s d j h -> Phi s d j hfactor phi = funComp . vcomp (rightAdj phi) epsilon
Here vcomp is the vertical composition of 2-cells:
vcomp :: (Functor f, Functor g, Functor h , Profunctor p, Profunctor q, Profunctor r, Profunctor s) => Cell f g p r -> Cell g h q s -> Cell f h (Procompose q p) (Procompose s r)vcomp fg_pr gh_qs (Procompose qxc pax) = Procompose (gh_qs qxc) (fg_pr pax)
and funComp is hom-functor composition:
funComp :: Procompose (->) (->) a b -> (a -> b)funComp (Procompose f g) = f . g
The computational meaning of the universal construction is that, in order to define a 2-cell (natural transformation) from some functor s to Ran j d along a profunctor h, it’s enough to provide a 2-cell from s to d along a composite Procompose j h.
Left Kan extensions
We can apply similar generalization to left Kan extensions. This time we start with the unit given by the 2-cell:
The universal condition that defines the pointwise left Kan extension of a vertical 1-cell along a horizontal 1-cell
is given by the following unique factorization:
Left Kan extensions in Haskell
In Haskell, we define the left Kan extension along a profunctor as an existential data type:
data Lan j d a where Lan :: j x a -> d x -> Lan j d a
This is a direct translation of the coend formula:
The unit is a 2-cell:
eta :: (Profunctor j, Functor d) => Cell d (Lan j d) j (->)eta jab da = Lan jab da
The universal condition states that, for any 2-cell:
type Phi s d j h = Cell d s (Procompose h j) (->)
there is a unique 2-cell:
type Phi' s d j h = Cell (Lan j d) s h (->)
given by the mapping:
leftAdj :: (Profunctor j, Profunctor h, Functor d, Functor s) => Phi s d j h -> Phi' s d j hleftAdj phi hac (Lan jxa dx) = phi (Procompose hac jxa) dx
that uniquely factorizes through the unit eta:
factor :: (Profunctor j, Profunctor h, Functor d, Functor s) => Phi s d j h -> Phi s d j hfactor phi = funComp . vcomp eta (leftAdj phi)
Again, computationally, this defines a mapping-out property of the left Kan extension.
Complete Haskell code is available here: left Kan extensions, right Kan extensions.





Leave a Reply