与类型族匹配时出现Coq类型错误
我试图从内存中重新实现一个示例。我写道:与类型族匹配时出现Coq类型错误,coq,Coq,我试图从内存中重新实现一个示例。我写道: Inductive myType : Set := MyNat | MyBool. Definition typeDenote (t : myType) : Set := match t with | MyNat => nat | MyBool => bool end. Inductive unaryOp : myType -> myType -> Set := | Twice : unaryOp My
Inductive myType : Set := MyNat | MyBool.
Definition typeDenote (t : myType) : Set :=
match t with
| MyNat => nat
| MyBool => bool
end.
Inductive unaryOp : myType -> myType -> Set :=
| Twice : unaryOp MyNat MyNat.
Definition twice (n:nat) : nat := n + n.
Definition tunaryDenote (a b : myType) (t : unaryOp a b)
: typeDenote a -> typeDenote b :=
match t with
| Twice => twice
end.
由此产生的错误是:
Toplevel input, characters 125-130
> | Twice => twice
> ^^^^^
Error: In environment
a : myType
b : myType
t : unaryOp a b
The term "twice" has type "nat -> nat" while it is expected to have type
"forall H : typeDenote ?141, typeDenote ?142"
我不明白这个错误信息。我认为一旦
上的匹配两次成功:unaryOp MyNat MyNat
,Coq就会推断a
和b
是MyNat
s,因此typereferencea->typereferenceb≡ nat->nat
,使两次成为返回值的完美候选。我哪里出错了?我认为答案是Coq的类型推断是有限的,不能进行您希望它进行的推理
Coq的类型推断不是任意计算,而是简单的统一。它看了两遍,了解它是nat->nat
,并得出结论,它不是typereferencea->typereferenceb
形式的(语法上)
如果它在进行计算,它很可能是非终止的,因为它的类型系统非常复杂,所以你可以在那里对非平凡的计算进行编码。就像@AntonTrunov所说的,它在我的Coq 8.5pl1上进行了类型检查,没有任何问题。但是,如果您需要为您的版本添加一些额外的注释来接受函数,您需要弄清楚该怎么做
我猜你想要一个匹配。。。在里面返回。。。用
表示返回类型应通过在类型unaryOp a b
处匹配t获得的信息进行细化(实际上:a
和b
将在分支中取具体值两次)
这是使用该技术得到的定义:
Definition tunaryDenote (a b : myType) (t : unaryOp a b)
: typeDenote a -> typeDenote b :=
match t in unaryOp a b return typeDenote a -> typeDenote b with
| Twice => twice
end.
我尝试了一个更新版本的Coq,正如其他人所说,它在Coq 8.5上进行了无问题的打字检查 最后的分析看起来非常好,所以我已经完全按照原样尝试了您的代码,但是Coq根本没有抱怨(使用COQV8.4pl6和v8.5pl2进行了检查)。