我可以使用类型类型在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
的实例,然后在id : A
上进行参数化来添加其他参数(例如,monoid的标识元素)。但是,为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中的类型类。
答案 0 :(得分:5)
<强>参考文献:强>
Coq中类型类的规范引用 - 超出the manual - this paper和the thesis(法语)Matthieu Sozeau。在a recent paper和my thesis中,研究级别的规范参考文献(具有不同的观点)较少。您还应该花一些时间在Freenode上的#coq频道,并订阅the mailing list。
您的问题:
语法问题本身不是Classes
,而是maximally inserted implicit arguments。 Monoid
和AbelianMonoid
类型在您的定义中(隐式)参数化参数,按此顺序,包括域类型,操作和标识 - 由索引打印这些记录类型时,您看到的依赖产品已完全展开。当您提及相关产品时,它们会自动填充,而不需要它们的参数。
实际上,如果留给自己的设备,隐式参数解析将自动插入所需的参数参数(对于依赖于它们的两种产品:P
和M
的类型)。您只需要通过指定各种标识符的变量来指定这些标识符之间的约束,在适当的时候区分:
Class Semiring A mul add `(P : AbelianMonoid A mul) `(M : Monoid A add) := {
}.
结果:
> Print Semiring.
Record Semiring (A : Type) (mul add : A -> A -> A)
(M0 : Semigroup mul) (id0 : A) (M : Monoid M0 id0)
(P : AbelianMonoid M) (M1 : Semigroup add) (id1 : A)
(M : Monoid M1 id1) : Type := Build_Semiring { }
For Semiring: Arguments M0, id0, M, M1, id1 are implicit and maximally
inserted
For Semiring: Argument scopes are [type_scope _ _ _ _ _ _ _ _ _]
For Build_Semiring: Argument scopes are [type_scope _ _ _ _ _ _ _ _ _]
注意阿贝尔幺半群和幺半群的身份这个时间是截然不同的。如果您对加法和乘法结构具有相同的标识元素,那么训练自己编写您想要的记录类型(也就是类)是一个很好的练习(即使它几乎没有数学意义)。