我可以使用类型类在 Coq 中天真地构建代数结构的层次结构。我在查找有关 Coq 类型类的语法和语义的资源时遇到了一些麻烦。但是,我相信以下是半群、幺半群和交换幺半群的正确实现:
Class Semigroup {A : Type} (op : A -> A -> A) : Type := {
op_associative : forall x y z : A, op x (op y z) = op (op x y) z
}.
Class Monoid `(M : Semigroup) (id : A) : Type := {
id_ident_left : forall x : A, op id x = x;
id_ident_right : forall x : A, op x id = x
}.
Class AbelianMonoid `(M : Monoid) : Type := {
op_commutative : forall x y : A, op x y = op y x
}.
如果我理解正确,可以通过首先声明Monoid
的实例Semigroup
,然后参数化 on来添加其他参数(例如,幺半群的标识元素) id : A
。但是,为 构建的记录中发生了一些奇怪的事情AbelianMonoid
。
< Print Monoid.
Record Monoid (A : Type) (op : A -> A -> A) (M : Semigroup op)
(id : A) : Type := Build_Monoid
{ id_ident_left : forall x : A, op id x = x;
id_ident_right : forall x : A, op x id = x }
< Print AbelianMonoid.
Record AbelianMonoid (A : Type) (op : A -> A -> A)
(M0 : Semigroup op) (id0 : A) (M : Monoid M0 id0) :
Type := Build_AbelianMonoid
{ op_commutative : forall x y : A, op x y = op y x }
这发生在我试图为半组构建一个类时。我认为以下语法是正确的:
Class Semiring `(P : AbelianMonoid) `(M : Monoid) := {
...
}.
但是,我无法消除正确的运算符和标识元素的歧义。打印记录揭示了上述问题。所以我有两个问题:第一,如何正确声明类Monoid
;第二,如何消除超类中的函数歧义?
我真正想要的是一个很好的资源,它清楚地解释了 Coq 的类型类,而没有过时的语法。例如,我认为 Hutton 的书清楚地解释了 Haskell 中的类型类。