型クラスを使用して、代数構造の階層を 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
。しかし、 のために構築されたレコードで奇妙なことが起こってい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) := {
...
}.
ただし、正しい演算子と ID 要素を明確にすることはできませんでした。レコードを印刷すると、上記の問題が明らかになりました。したがって、2 つの質問があります。まず、クラスを正しく宣言するにはどうすればよいですかMonoid
。第二に、スーパークラスの関数をどのように明確にしますか?
私が本当に欲しいのは、時代遅れの構文なしで Coq の型クラスを明確に説明する優れたリソースです。たとえば、Hatton の本では、Haskell の型クラスが明確に説明されていると思いました。