我正在用《软件基础》一书研究Coq中的类型类。
运行以下内容:
Class Eq A :=
{
eqb: A -> A -> bool;
}.
Notation "x =? y" := (eqb x y) (at level 70).
Instance eqBool : Eq bool :=
{
eqb := fun (b c : bool) =>
match b, c with
| true, true => true
| true, false => false
| false, true => false
| false, false => true
end
}.
Compute (true =? false).
我按预期收到消息= false : bool
。
但是,如果我改为执行以下操作,
Class Eq A :=
{
eqb: A -> A -> bool;
eqb_refl: forall (x : A), eqb x x = true;
}.
Notation "x =? y" := (eqb x y) (at level 70).
Instance eqBool : Eq bool :=
{
eqb := fun (b c : bool) =>
match b, c with
| true, true => true
| true, false => false
| false, true => false
| false, false => true
end
}.
Proof.
intros []; reflexivity.
Qed.
Compute (true =? false).
我收到消息= (let (eqb, _) := eqBool in eqb) true false : bool
。
我似乎无法简化此表达式,并且不确定出什么地方以及出了什么问题。
我该如何使用额外的假设来定义上述类型类,并且仍然能够使用我定义的实例(即,获得与以前相同的消息)?
非常感谢!
答案 0 :(得分:2)
Qed
命令创建不透明的定义,这些定义永远不会被Compute
之类的命令显示。您可以使用Program Instance
命令使Coq仅使证明义务不透明:
Require Import Coq.Program.Tactics.
Class Eq A :=
{
eqb: A -> A -> bool;
eqb_refl: forall (x : A), eqb x x = true;
}.
Notation "x =? y" := (eqb x y) (at level 70).
Program Instance eqBool : Eq bool :=
{
eqb := fun (b c : bool) =>
match b, c with
| true, true => true
| true, false => false
| false, true => false
| false, false => true
end
}.
Next Obligation. now destruct x. Qed.
Compute (true =? false).