与类型族匹配时出现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进行了检查)。