Boundaries
The Data.Boundary module holds a single type: Boundary.
Its role is to hold two types, in a sense, it’s an alias for
Pair Type Type. In haskell one could write type B = (Type, Type)
for the same definition.
module Data.Boundary
%default totalWhy do we need this? It is because boundaries make the representation of the category of lenses easier to write. It also makes the move from plain lenses into dependent lenses easier to follow.
||| Type boundaries
public export
record Boundary where
constructor MkB
π1 : Type
π2 : TypeBecause it is a record, it is given two projections π1 and π2
so that we can extract each type boundary.
One of the benefits of making it its own type is that we can write functions like the following just for boundaries:
public export
cartesian : Boundary -> Boundary -> Boundary
cartesian a b = (MkB (a.π1, b.π1) (a.π2, b.π2))
public export
cocartesian : Boundary -> Boundary -> Boundary
cocartesian a b = MkB (Either a.π1 b.π1) (Either a.π2 b.π2)We also provide a constructor to supply only one type when both are the same.
And we create a shorthand for the unit boundary.
public export
Dup : Type -> Boundary
Dup ty = MkB ty ty
public export
BUnit : Boundary
BUnit = MkB Unit UnitBy themselves, boundaries do not do much, but they are instrumental in identifying lense as a morphism between two things, those things are the boundaries we defined here.