我正在尝试从内存中重新实现CPDT的示例。我写道:
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"
我不明白这个错误信息。我认为,一旦Twice : unaryOp MyNat MyNat
上的匹配成功,Coq就会推断a
和b
为MyNat
,因此typeDenote a -> typeDenote b ≡ nat -> nat
,twice
返回值的完美候选者。我哪里出错?
答案 0 :(得分:1)
就像@AntonTrunov所说的那样,我的Coq 8.5pl1没有任何问题。但是,如果您需要为您的版本添加一些额外的注释来接受该功能,您需要have a look at this section of the manual来确定要做什么。
我的猜测是你希望有一个match ... in ... return ... with
表示返回类型应该精炼通过匹配类型unaryOp a b
获得的信息(确实:a
和b
将在Twice
分支中采用具体值。
这是您使用该技术获得的定义:
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.
答案 1 :(得分:0)
我认为答案是Coq的类型推断是有限的,并没有做你想要的推理。
Coq的类型推断不是任意计算,而是简单统一。它会查看twice
,了解它是nat->nat
,并得出结论:它不是(语法上)typeDenote a -> TypeDenote b
形式。
如果它正在进行计算,它可能是非终止的,因为它的类型系统非常复杂,所以你可以在那里编码非平凡的计算。
答案 2 :(得分:0)
我尝试了更新版本的Coq,和其他人一样说,它在Coq 8.5上没有问题。 :)