DoNotation.agda 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. -- Using do-notation to implement a type checker for simply-typed
  2. -- lambda-calculus.
  3. module _ where
  4. open import Agda.Builtin.Nat hiding (_==_)
  5. open import Agda.Builtin.List
  6. open import Agda.Builtin.Equality
  7. open import Agda.Builtin.String
  8. -- Preliminaries --
  9. --- Decidable equality ---
  10. data ⊥ : Set where
  11. ¬_ : Set → Set
  12. ¬ A = A → ⊥
  13. data Dec (P : Set) : Set where
  14. yes : P → Dec P
  15. no : ¬ P → Dec P
  16. record Eq (A : Set) : Set where
  17. field _==_ : (x y : A) → Dec (x ≡ y)
  18. open Eq {{...}}
  19. --- Functors, Applicatives, and Monads ---
  20. record Functor (F : Set → Set) : Set₁ where
  21. field fmap : ∀ {A B} → (A → B) → F A → F B
  22. open Functor {{...}}
  23. record Applicative (F : Set → Set) : Set₁ where
  24. field
  25. pure : ∀ {A} → A → F A
  26. _<*>_ : ∀ {A B} → F (A → B) → F A → F B
  27. overlap {{super}} : Functor F
  28. open Applicative {{...}}
  29. record Monad (M : Set → Set) : Set₁ where
  30. field
  31. _>>=_ : ∀ {A B} → M A → (A → M B) → M B
  32. overlap {{super}} : Applicative M
  33. _>>_ : ∀ {A B} → M A → M B → M B
  34. m >> m' = m >>= λ _ → m'
  35. open Monad {{...}}
  36. data Maybe (A : Set) : Set where
  37. nothing : Maybe A
  38. just : A → Maybe A
  39. instance
  40. FunctorMaybe : Functor Maybe
  41. fmap {{FunctorMaybe}} f nothing = nothing
  42. fmap {{FunctorMaybe}} f (just x) = just (f x)
  43. ApplicativeMaybe : Applicative Maybe
  44. pure {{ApplicativeMaybe}} = just
  45. _<*>_ {{ApplicativeMaybe}} nothing _ = nothing
  46. _<*>_ {{ApplicativeMaybe}} (just _) nothing = nothing
  47. _<*>_ {{ApplicativeMaybe}} (just f) (just x) = just (f x)
  48. MonadMaybe : Monad Maybe
  49. _>>=_ {{MonadMaybe}} nothing f = nothing
  50. _>>=_ {{MonadMaybe}} (just x) f = f x
  51. --- List membership ---
  52. infix 2 _∈_
  53. data _∈_ {A : Set} (x : A) : List A → Set where
  54. zero : ∀ {xs} → x ∈ x ∷ xs
  55. suc : ∀ {y xs} → x ∈ xs → x ∈ y ∷ xs
  56. rawIndex : ∀ {A} {x : A} {xs} → x ∈ xs → Nat
  57. rawIndex zero = zero
  58. rawIndex (suc i) = suc (rawIndex i)
  59. -- Simply typed λ-calculus --
  60. infixr 7 _=>_
  61. data Type : Set where
  62. nat : Type
  63. _=>_ : Type → Type → Type
  64. --- Decidable equality for Type ---
  65. private
  66. =>-inj₁ : ∀ {σ₁ σ₂ τ₁ τ₂} → (σ₁ => τ₁) ≡ (σ₂ => τ₂) → σ₁ ≡ σ₂
  67. =>-inj₁ refl = refl
  68. =>-inj₂ : ∀ {σ₁ σ₂ τ₁ τ₂} → σ₁ => τ₁ ≡ σ₂ => τ₂ → τ₁ ≡ τ₂
  69. =>-inj₂ refl = refl
  70. instance
  71. EqType : Eq Type
  72. _==_ {{EqType}} nat nat = yes refl
  73. _==_ {{EqType}} nat (τ => τ₁) = no λ()
  74. _==_ {{EqType}} (σ => σ₁) nat = no λ()
  75. _==_ {{EqType}} (σ => σ₁) (τ => τ₁) with σ == τ | σ₁ == τ₁
  76. ... | yes refl | yes refl = yes refl
  77. ... | yes refl | no neq = no λ eq → neq (=>-inj₂ eq)
  78. ... | no neq | _ = no λ eq → neq (=>-inj₁ eq)
  79. --- Raw terms ---
  80. data Expr : Set where
  81. var : Nat → Expr
  82. app : Expr → Expr → Expr
  83. lam : Type → Expr → Expr
  84. lit : Nat → Expr
  85. suc : Expr
  86. --- Well-typed terms ---
  87. Context = List Type
  88. data Term (Γ : Context) : Type → Set where
  89. var : ∀ {τ} (x : τ ∈ Γ) → Term Γ τ
  90. app : ∀ {σ τ} (s : Term Γ (σ => τ)) (t : Term Γ σ) → Term Γ τ
  91. lam : ∀ σ {τ} (t : Term (σ ∷ Γ) τ) → Term Γ (σ => τ)
  92. lit : (n : Nat) → Term Γ nat
  93. suc : Term Γ (nat => nat)
  94. --- Erasing types ---
  95. forgetTypes : ∀ {Γ τ} → Term Γ τ → Expr
  96. forgetTypes (var x) = var (rawIndex x)
  97. forgetTypes (app s t) = app (forgetTypes s) (forgetTypes t)
  98. forgetTypes (lam σ t) = lam σ (forgetTypes t)
  99. forgetTypes (lit n) = lit n
  100. forgetTypes suc = suc
  101. --- Type checking ---
  102. TC = Maybe
  103. typeError : ∀ {A} → TC A
  104. typeError = nothing
  105. data WellTyped (Γ : Context) (e : Expr) : Set where
  106. ok : (σ : Type) (t : Term Γ σ) → forgetTypes t ≡ e → WellTyped Γ e
  107. data InScope (Γ : Context) (n : Nat) : Set where
  108. ok : (σ : Type) (i : σ ∈ Γ) → rawIndex i ≡ n → InScope Γ n
  109. infix 2 _∋_
  110. pattern _∋_ σ x = ok σ x refl
  111. lookupVar : ∀ Γ n → TC (InScope Γ n)
  112. lookupVar [] n = typeError
  113. lookupVar (σ ∷ Γ) zero = pure (σ ∋ zero)
  114. lookupVar (σ ∷ Γ) (suc n) = do
  115. τ ∋ i ← lookupVar Γ n
  116. pure (τ ∋ suc i)
  117. -- Correct-by-construction type inference
  118. infer : ∀ Γ e → TC (WellTyped Γ e)
  119. infer Γ (var x) = do
  120. τ ∋ i ← lookupVar Γ x
  121. pure (τ ∋ var i)
  122. infer Γ (app e e₁) = do
  123. σ => τ ∋ s ← infer Γ e where nat ∋ s → typeError
  124. σ′ ∋ t ← infer Γ e₁
  125. yes refl ← pure (σ == σ′) where no _ → typeError
  126. pure (τ ∋ app s t)
  127. infer Γ (lam σ e) = do
  128. τ ∋ t ← infer (σ ∷ Γ) e
  129. pure (σ => τ ∋ lam σ t)
  130. infer Γ (lit x) = pure (nat ∋ lit x)
  131. infer Γ suc = pure (nat => nat ∋ suc)
  132. -- Check that it works
  133. test : infer [] (lam (nat => nat) (lam nat (app (var 1) (var 0)))) ≡
  134. pure ((nat => nat) => nat => nat ∋
  135. lam (nat => nat) (lam nat (app (var (suc zero)) (var zero))))
  136. test = refl