为什么Coq会在其核心语言中包含let表达式


9

Coq在其核心语言中包含let表达式。我们可以这样将let表达式转换为应用程序: let x : t = v in b ~> (\(x:t). b) v 我知道这并不总是可行,因为v在进行typechecking时该值不可用b。但是,可以通过特殊外壳对表单应用程序进行类型检查来轻松解决此问题(\(x:t). b) v。这使我们可以在进行类型检查时以特殊情况为代价删除let表达式。为什么Coq include仍然包含let表达式?它们是否还有其他优点(除了不需要特殊情况)?


4
您的建议听起来像添加一个hack来避免使用let表达式,但是没有a)没有理由避免使用let表达式,它们也很方便,并且b)在您的核心语言中添加hack并不是一个好主意。
德里克·埃尔金斯

Answers:


23

常见的误解是我们可以将let-expresions 转换为应用程序。let x : t := b in v和之间的区别(fun x : t => v) b是,在let-expression中,v我们知道类型检查期间x等于b,但是在应用程序中我们不知道(子表达式fun x : t => v必须自己理解)。

这是一个例子:

(* Dependent type of vectors. *)
Inductive Vector {A : Type} : nat -> Type :=
  | nil : Vector 0
  | cons : forall n, A -> Vector n -> Vector (S n).

(* This works. *)
Check (let n := 0 in cons n 42 nil).

(* This fails. *)
Check ((fun (n : nat) => cons n 42 nil) 0).

您关于使应用程序(fun x : t => v) b成为特殊情况的建议实际上是行不通的。让我们仔细考虑一下。

例如,继续上面的示例,您将如何处理?

Definition a := (fun (n : nat) => cons n 42 nil).
Check a 0.

大概这是行不通的,因为a无法键入,但是如果我们展开其定义,则会得到类型正确的表达式。您认为用户会喜欢我们还是讨厌我们的设计决定?

e₁ e₂e₁λ

您还将打破基本定理,该基本定理说类型良好的表达式的每个子表达式都是类型良好的。这与引入nullJava 一样明智。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.