我想定义一个函数app_1
,它将n
- ary函数f : X ^^ n --> Y
转换为新函数f' : (Z -> X) ^^ n --> Y
,前提是有z : Z
对其所有论点适用一次。例如,
Example ex1 : app_1 plus 2 S pred = 4.
trivial. Qed.
app_1 plus 2
能够将一元函数S
和pred
作为参数,因为它首先将它们都应用于2
,然后将结果应用于{{ 1}}。
这是我尝试定义的plus
:
app_1
哪个不起作用,因为Coq不喜欢条款Fixpoint app_1 {X Y Z : Type} {n : nat}
(f : X ^^ n --> Y) (z : Z) :
(Z -> X) ^^ n --> Y :=
match n return ((Z -> X) ^^ n --> Y) with
| O => f
| S n' => fun g => app_1 (f (g z)) z
end.
,并说:
| O => f
但如果The term "f" has type "X ^^ n --> Y" while it is expected to have type "(Z -> X) ^^ 0 --> Y".
,n = O
,那么这不是类型不匹配。问题是Coq无法使用上下文信息X ^^ n --> Y = X ^^ 0 --> Y = Y = (Z -> X) ^^ 0 --> Y
来确定等价性。
一些初步搜索显示这是一个众所周知的问题,但如何将这些讨论应用于此案例有点令人困惑。例如,an almost identical question on SO是使用n = O
解决的,这也是我(有点)上面尝试过的,但无济于事。
有没有办法让这种模式匹配起作用?
答案 0 :(得分:3)
像往常一样,你必须应用护航模式(参见Adam Chlipala的CPDT书)并使模式匹配返回函数:
Require Import Coq.Numbers.NaryFunctions.
Fixpoint app_1 {X Y Z : Type} {n : nat}
(f : X ^^ n --> Y) (z : Z) :
(Z -> X) ^^ n --> Y :=
match n return (X ^^ n --> Y) -> ((Z -> X) ^^ n --> Y) with
| O => fun f => f
| S n' => fun f g => app_1 (f (g z)) z
end f.
为了使用有关f
类型的信息,需要对其进行重新抽象:在每个分支中,它都具有正确的类型。
答案 1 :(得分:2)
在n
完善之后,您可以延迟获取参数:
Fixpoint app_1 {X Y Z : Type} {n : nat}
: (X ^^ n --> Y) -> Z -> (Z -> X) ^^ n --> Y :=
match n return (X ^^ n --> Y) -> Z -> (Z -> X) ^^ n --> Y with
| O => fun f _ => f
| S n' => fun f z g => app_1 (f (g z)) z
end.
当绑定f
时,其类型已更改为X ^^ 0 --> Y
,因此可以解决问题。
Fixpoint app_1 {X Y Z : Type} {n : nat} (f: X ^^ n --> Y) (z: Z)
: (Z -> X) ^^ n --> Y :=
match n return X ^^ n --> Y -> ((Z -> X) ^^ n --> Y) with
| O => fun f => f
| S n' => fun f' g => app_1 (f' (g z)) z
end f.