我无法理解Coq中类型类和依赖记录之间的区别.参考手册给出了类型类的语法,但没有说明它们到底是什么以及如何使用它们.一些思考和搜索揭示了类型类本质上是具有一些语法糖的依赖
作为示例,请考虑以下代码,该代码定义了一个monoid类型类,使用自然数来实例化它:
Class monoid A := Monoid { op : A -> A -> A; id : A; opA : forall x y z, op x (op y z) = op (op x y) z; idL : forall x, op id x = x; idR : forall x, op x id = x }. Require Import Arith. Instance nat_plus_monoid : monoid nat := {| op := plus; id := 0; opA := plus_assoc; idL := plus_O_n; idR := fun n => eq_sym (plus_n_O n) |}.
使用类型类推断,我们可以使用任何直接用于nat的任何monoid的定义,而不提供类型类参数,例如:
Definition times_3 (n : nat) := op n (op n n).
但是,如果通过“记录和定义”替换“类和实例”将上述定义转换为常规记录,则相同的定义将失败:
Toplevel input, characters 38-39: Error: In environment n : nat The term "n" has type "nat" while it is expected to have type "monoid ?11".
对类型类的唯一警告是实例推理引擎有时会有点丢失,导致出现难以理解的错误消息.话虽这么说,但鉴于这种可能性甚至无法在那里获得,它并不是真正的依赖记录.