module Type where
To begin, we get all our infix declarations out of the way.
infix 4 _∋⋆_ infix 4 _⊢⋆_ infixl 5 _,⋆_ infix 6 Π infixr 7 _⇒_ infix 5 ƛ infixl 7 _·_ infix 9 S
open import Data.Vec using (Vec) open import Data.List using (List) open import Utils using (Kind;J;K) open Kind
A type context is either empty or extends a type context by a type variable of a given kind.
data Ctx⋆ : Set where ∅ : Ctx⋆ _,⋆_ : Ctx⋆ → Kind → Ctx⋆
Let Φ
, Ψ
, Θ
range over type contexts:
variable Φ Ψ Θ : Ctx⋆
Type variables are not named, they are numbered (de Bruijn indices).
A type variable is indexed by its context and kind. For a given context, it’s impossible to construct a variable that is out of scope.
data _∋⋆_ : Ctx⋆ → Kind → Set where Z : ------------- Φ ,⋆ J ∋⋆ J S : Φ ∋⋆ J ------------- → Φ ,⋆ K ∋⋆ J
Let α
, β
range over type variables
A type is indexed by its context and kind. Types are intrinsically scoped and kinded: it’s impossible to construct an ill-kinded application and it’s impossible to refer to a variable that is not in scope.
A type is either a type variable, a pi type, a function type, a
lambda, an application, an iso-recursive type μ
, a size, or a type
constant (base type). Note that recursive types range over an
arbitrary kind k
which goes beyond standard iso-recursive types. Also note that Π
,
⇒
, and µ
are effectively base types as they live at kind *
.
The Sum of Products types are based on Agda’s standard Vectors and Lists.
data _⊢⋆_ : Ctx⋆ → Kind → Set open import Builtin.Constant.Type using (TyCon) data _⊢⋆_ where ` : Φ ∋⋆ J -------- → Φ ⊢⋆ J Π : Φ ,⋆ K ⊢⋆ * ----------- → Φ ⊢⋆ * _⇒_ : Φ ⊢⋆ * → Φ ⊢⋆ * ------ → Φ ⊢⋆ * ƛ : Φ ,⋆ K ⊢⋆ J ----------- → Φ ⊢⋆ K ⇒ J _·_ : Φ ⊢⋆ K ⇒ J → Φ ⊢⋆ K ------ → Φ ⊢⋆ J μ : Φ ⊢⋆ (K ⇒ *) ⇒ K ⇒ * → Φ ⊢⋆ K --------------------- → Φ ⊢⋆ * ^ : TyCon K ------- → Φ ⊢⋆ K con : Φ ⊢⋆ ♯ ------ → Φ ⊢⋆ * -- Sum of Products SOP : ∀{n} → Vec (List (Φ ⊢⋆ *)) n ---------------------- → Φ ⊢⋆ *
Let A
, B
, C
range over types:
variable A A' B B' C C' : Φ ⊢⋆ J