Cached at:
05/18/26, 06:53 AM
# Profunctor Equipment in Haskell
Source: [https://bartoszmilewski.com/2026/05/16/profunctor-equipment-in-haskell/](https://bartoszmilewski.com/2026/05/16/profunctor-equipment-in-haskell/)
Previously:[Profunctor Equipment](https://bartoszmilewski.com/2026/04/24/profunctor-equipment/)\.
To make things more palatable for programmers, I decided to provide a toy implementation of some of the equipments in Haskell\. The advantage of this encoding is that it can be verified by the compiler, and I still trust the compiler more than I trust the AI\.
A more adequate implementation would require a full\-blown dependently typed language, but if we restrict ourselves to just a single category and work only with endo\-functors and endo\-profunctors, we can get at least some intuitions\. If you want to see a more elaborate version, see the[proarrows](https://github.com/sjoerdvisscher/proarrow/)library by Sjoerd Visscher\.
The only 0\-cell I’ll be using is the Haskell category of types and functions\. For vertical 1\-cells I’ll use the standard library implementation of`Functor`, and for horizontal ones I’ll use`Profunctor`\.
A 2\-cell in:
[](https://i0.wp.com/bartoszmilewski.com/wp-content/uploads/2026/04/Screenshot-2026-04-18-at-16.48.46.png?ssl=1)
is implemented as a natural transformation:
```
type Cell f g h j = forall a c . h a c -> j (f a) (g c)
```
The`forall`serves as a universal quantifier\.
The horizontal composition of such cells is given by:
```
hcomp :: (Functor f, Functor f', Functor g, Functor g' , Profunctor h, Profunctor j, Profunctor k) => Cell f g h j -> Cell f' g' j k -> Cell (Compose f' f) (Compose g' g) h khcomp fg_hj fg_jk hac = dimap getCompose Compose $ fg_jk (fg_hj hac)
```
I used the library definition of functor composition:
```
newtype Compose f g a = Compose { getCompose :: f (g a) }
```
Vertical composition of cells uses a more elaborate profunctor composition:
```
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)
```
Profunctor composition is defined using a coend\. In Haskell, we implement a coend:

as an existential type:
```
data Procompose p q d c where Procompose :: p x c -> q d x -> Procompose p q d c
```
Here, x is a type that’s not in the argument list, so it’s interpreted using the existential counterpart of`forall`\.
This is the horizontal unit cell:
```
type Hunit p = Cell Identity Identity p phUnit :: Profunctor p => Hunit phUnit = dimap runIdentity Identity
```
and here’s its vertical counterpart:
```
type Vunit f a b = Cell f f (->) (->)vUnit :: Functor f => Vunit f a bvUnit = fmap
```
I used the library implementation of the`Identity`functor, and the type constructor`\(\-\>\)`for the hom\-profunctor–the unit of profunctor composition\. The unit laws are satisfied up to isomorphism\.
The companion and the conjoint are synonyms of the library types`Costar`and`Star`:
```
newtype Star f d c = Star { runStar :: d -> f c }newtype Costar f d c = Costar { runCostar :: f d -> c }
```
```
type Companion f d c = Costar f d ctype Conjoint f d c = Star f d c
```
The companion unit and counit cells:
[](https://i0.wp.com/bartoszmilewski.com/wp-content/uploads/2026/04/Screenshot-2026-04-19-at-19.15.45.png?ssl=1)
are given by, respectively:
```
type CompUnit f = Cell Identity f (->) (Costar f)compUnit :: Functor f => CompUnit fcompUnit h = Costar (fmap (h . runIdentity))
```
and
```
type CompCoUnit f = Cell f Identity (Costar f) (->)compCoUnit :: Functor f => CompCoUnit f compCoUnit (Costar h) = Identity . h
```
Similarly for the conjoint:
[](https://i0.wp.com/bartoszmilewski.com/wp-content/uploads/2026/04/Screenshot-2026-04-19-at-21.59.56.png?ssl=1)
```
type ConjUnit f = Cell f Identity (->) (Star f)conjUnit :: Functor f => ConjUnit f conjUnit h = Star (fmap (Identity . h))
```
and:
```
type ConjCoUnit f = Cell Identity f (Star f) (->)conjCoUnit :: Functor f => ConjCoUnit f conjCoUnit (Star h) = h . runIdentity
```
More advanced constructions would require the definition of categories internal to Hask and the use of dependent types\.
Haskell code is available[here](https://v15.next.forgejo.org/BartoszMilewski/Categories/src/branch/main/Equipment.hs)\.