Coq中的多个类型类继承

时间:2014-12-30 10:04:05

标签: typeclass coq

我一直在尝试在Coq中创建一个小的类型类层次结构,尽管在stackoverflow上有一些我认为会成为解决方案的答案,但我无法取得进展,特别是Building a class hierarchy in Coq?

这就是我所拥有的:

Class Unfoldable (C : Type -> Type) (A : Type)
  (insert : A -> C A -> C A)
  (empty : C A) : Type :=
{
  insert_neq : forall (x y : A) (h : C A),
    insert x h <> insert y h -> x <> y;
  empty_insert_eq : forall x y : A,
    insert x empty = insert y empty <-> x = y
}.

Class Foldable (C : Type -> Type) (A B : Type)
  (foldr : (A -> B -> B) -> B -> C A -> B) : Type :=
{
  (* Foldable properties??? *)
}.

Class Collection C A {B} insert empty foldr
  `{F : Foldable C A B foldr}
  `{U : Unfoldable C A insert empty} :=
{
  collection_id : forall h,
    foldr insert empty h = h
}.

Print Collection.

以下是错误消息:

Error:
In environment
Collection :
forall (C : Type -> Type) (A B : Type) (insert : A -> C A -> C A)
  (empty : C A) (foldr : (A -> B -> B) -> B -> C A -> B),
Foldable C A B foldr -> Unfoldable C A insert empty -> Type
C : Type -> Type
A : Type
B : Type
insert : A -> C A -> C A
empty : C A
foldr : (A -> B -> B) -> B -> C A -> B
F : Foldable C A B foldr
U : Unfoldable C A insert empty
h : ?17
The term "insert" has type "A -> C A -> C A"
 while it is expected to have type "A -> B -> B".

C A不应该有Type类型,因此适合B吗?

很抱歉无法提供更多信息。我真的不太了解Coq。谢谢你的帮助。

1 个答案:

答案 0 :(得分:2)

我自己对类型类知之甚少,但B不需要变量吗?通过将其与foldr分开,您可以将其修复。我认为只有CA修复才有意义。

Class Foldable (C : Type -> Type) (A : Type)
  (foldr : forall B, (A -> B -> B) -> B -> C A -> B) : Type :=
{
  (* Foldable properties??? *)
}.

Class Collection C A insert empty foldr
  `{F : Foldable C A foldr}
  `{U : Unfoldable C A insert empty} :=
{
  collection_id : forall h, foldr (C A) insert empty h = h
}.

如果您确实需要修复B,则必须将其设置为C A,因为这是insertempty返回的内容,但您不应该{{1}永远是B

C A

顺便说一下,Class Collection C A insert empty foldr `{F : Foldable C A (C A) foldr} `{U : Unfoldable C A insert empty} := { collection_id : forall h, foldr insert empty h = h }. 总是可证明的。

insert_neq

更新

在原始代码中,您有类似于以下内容的内容。

Axiom C : Type -> Type.
Axiom A : Type.
Axiom empty : C A.
Axiom insert : A -> C A -> C A.

Goal forall (x y : A) (h : C A), insert x h <> insert y h -> x <> y.
intros ? ? ? H1 H2.
apply H1.
rewrite H2.
apply eq_refl.
Qed.

这最后一个公理是错误的,因为Axiom C : Type -> Type. Axiom A : Type. Axiom B : Type. Axiom insert : A -> C A -> C A. Axiom empty : C A. Axiom foldr : (A -> B -> B) -> B -> C A -> B. (* Foldable properties??? *) Axiom insert_neq : forall (x y : A) (h : C A), insert x h <> insert y h -> x <> y. Axiom empty_insert_eq : forall x y : A, insert x empty = insert y empty <-> x = y. Axiom collection_id : forall h : C A, foldr insert empty h = h. 会返回foldr,而不是B。不能保证它们可以是同一个东西。

除非C A具有任何特定属性,否则您只能使B多态。

foldr

在这种情况下,Axiom C : Type -> Type. Axiom A : Type. Axiom insert : A -> C A -> C A. Axiom empty : C A. Axiom foldr : forall B : Type, (A -> B -> B) -> B -> C A -> B. (* Foldable properties??? *) Axiom insert_neq : forall (x y : A) (h : C A), insert x h <> insert y h -> x <> y. Axiom empty_insert_eq : forall x y : A, insert x empty = insert y empty <-> x = y. Axiom collection_id : forall h : C A, foldr (C A) insert empty h = h. 需要一个额外的参数:它返回的类型。 Coq中Haskell类型foldr的等价物是(a -> b -> b) -> b -> [a] -> b

我给出的第二个例子相当于以下内容。

forall a b : Type, (a -> b -> b) -> b -> list a -> b