-
Notifications
You must be signed in to change notification settings - Fork 0
Description
It would be nice to support well-typed-by-construction expression types, such as nested abstract syntax where we have expr : Type -> Type, we label both variables in expr V with labels of type V and we label binders with unit, and we have abs : unit -> expr (option V) -> expr V (i.e., a new binder extends V into option V); or intrinsically typed syntax where we have a type of type codes type, and we label binders with type and we label variables in expr ctx with indices of ctx, where ctx : list type, and where abs : forall (t : type), expr (t :: ctx) -> expr ctx.
I believe (one of) the construction(s) you need for this is to generalize monoid to dependent monoid. I haven't seen this anywhere in the literature, and as far as I know, @Soares came up with it:
Require Import Coq.Unicode.Utf8.
Reserved Infix "▷" (at level 70, right associativity).
Reserved Infix "⊙" (at level 40).
Notation "( x ; y ; .. ; z )" := (existT _ .. (existT _ x y) .. z) : core_scope.
Notation Σ := sigT (only parsing).
Import EqNotations.
Record DependentMonoid (X : Type) (M : X → Type) :=
{ ext : Σ M → X
where "x ▷ y" := (ext (x; y))
; I : ∀ {x : X}, unit → M x
; T : ∀ {x : X}, { y : M x & M (x ▷ y) } → M x
where "y ⊙ z" := (T (y; z))
; I_law : ∀ {x : X}, x = (x ▷ I tt)
; T_law : ∀ {x : X} {y : M x} {z : M (x ▷ y)}, ((x ▷ y) ▷ z) = (x ▷ (y ⊙ z))
; runit : ∀ {x : X} {y : M x} , y = y ⊙ I tt
; lunit : ∀ {x : X} {y : M (x ▷ I tt)}, y = I tt ⊙ rew [M] I_law in y
; assoc : ∀ {x : X} {y : M x} {z : M (x ▷ y)} {w : M ((x ▷ y) ▷ z)},
(y ⊙ (z ⊙ w)) = ((y ⊙ z) ⊙ rew [M] T_law in w)
}.Note that DependentMonoid X M is isomorphic to a category whose objects are X and whose morphisms from x to y are of type { m : M x | ext (x; m) = y }, where composition is given by T. Equivalently, a category with objects X and morphisms Hom x y is isomorphic to a dependent monoid with X := X and M x := { y : X & Hom x y } (ext is "target", i.e., fun v => projT1 (projT2 v), and T is composition). Said another way, a dependent monoid looks like a category where morphisms are indexed only on their source and not also on their target.
You can specialize this to a non-dependent monoid by setting X := unit.
Do you think this will allow handling nested abstract syntax and intrinsically typed syntax?