Here we define the proper GADT Seq
of sequences. It will be used several times in the examples.
module seq where open import map open import Data.List using ([] ; _∷_ ; [_]) open import Data.Vec renaming ([] to [||] ; _∷_ to _¦_ ; [_] to [|_|] ) open import Data.Unit renaming (tt to ∗) open import Data.Product using (_,_)
We introduce variables and contexts for the declaration of Seq
’s data constructors.
α β γ : mix-var α = tvar 0 β = tvar 1 γ = tvar 2 Γα : type-context {mix-var} Γα = ⟦ [| α |] ⟧ Γβγ : type-context {mix-var} Γβγ = ⟦ β ¦ γ ¦ [||] ⟧
We then define Seq
as usual, with a constructor const
producing a sequence from a piece of raw data, and a constructor pair
making a sequence of pairs from sequences of the pair’s constituent types.
Seq-id : id-TC-var Seq-id = 4 Seq-name : TC-var 1 Seq-name = TC Seq-id 1 const-id pair-id : id-data-constructor const-id = 40 pair-id = 41 const pair : data-constructor 1 const = const-id ∷ [ varᵀ α ] ⇒ᵀ [| (varᵀ α) |] pair = pair-id ∷ (appᵀ Seq-name [ [| varᵀ β |] ] ∷ appᵀ Seq-name [ [| varᵀ γ |] ] ∷ []) ⇒ᵀ [| ((varᵀ β) ×ᵀ (varᵀ γ)) |] Seq : user-defined {mix-var} 1 Seq = dataᵀ Seq-name whereᵀ (const ∷ pair ∷ []) Seq[_] = λ x → data-typeᵀ Seq [ [| x |] ] const[_] = λ x → dc const [| x |] pair[_,_] = λ x y → dc pair (x ¦ y ¦ [||] )
Finally, we justify the application of Seq
to a type expression.
⊢const : Γα ∥ ∅ ⊢ᶜ const ⊢const = dcᵀ-intro {G = Seq-name} (var-intro ∋-last , ∗) (var-intro ∋-last , ∗) ⊢pair : Γβγ ∥ (∅ , (1 , Seq-name)) ⊢ᶜ pair ⊢pair = dcᵀ-intro {G = Seq-name} (app-intro (var-intro (∋-rec ∋-last) , ∗) ∋-last , (app-intro (var-intro ∋-last , ∗) ∋-last , ∗)) (×-intro (var-intro (∋-rec ∋-last) ) (var-intro ∋-last) , ∗) ⊢Seq : ∀ {Γ χ φ} → _ → Γ ∥ χ ⊢ Seq[ φ ] ⊢Seq ⊢φ = data-intro {k = 1} {G = Seq-name} {Γcs = Γα ∷ Γβγ ∷ []} {χcs = ∅ ∷ (∅ , (1 , Seq-name)) ∷ []} (⊢const , (⊢pair , ∗)) (⊢φ , ∗)