所以我们可以有明确的参数,用()
表示
我们也可以有隐式参数,用{}
表示。
到目前为止一切顺利。
但是,为什么我们还需要专门针对类型类的[]
表示法?
以下两者之间有什么区别:
theorem foo {x : Type} : ∀s : inhabited x, x := sorry
theorem foo' {x : Type} [s : inhabited x] : x := sorry
答案 0 :(得分:1)
Lean的阐述者会自动插入隐式参数。您的两个定义中出现的{x : Type}
是隐式参数的一个示例:如果您有s : inhabited nat
,那么您可以编写foo s
,这将详细说明{{1}类型的术语1}},因为nat
参数可以从x
推断出来。
类型类参数是另一种隐式参数。 elaborator不是从后面的参数中推断出来,而是运行一个名为 type class resolution 的过程,它将尝试生成指定类型的术语。 (参见https://leanprover.github.io/theorem_proving_in_lean/theorem_proving_in_lean.pdf的第10章。)因此,你的s
实际上根本不会参数。如果可以从上下文推断出预期类型foo'
,精益将查找x
的实例并插入它:
inhabited x
在这里,精益推断def foo' {x : Type} [s : inhabited x] : x := default x
instance inh_nat : inhabited nat := ⟨3⟩
#eval (2 : ℕ) + foo' -- 5
必须是x
,并查找并插入nat
的实例,以便inhabited nat
单独阐述foo'
类型的术语1}}。