我有这种类型
Inductive coef :=
| Mycoef_ex2 : matrix -> coef
with matrix :=
| My_matrix : list (list coef) -> matrix.
Inductive my_type :=
| Mytype_ex1 : list my_type -> my_type
| Mytype_int : Z -> my_type
| Mytype_coef : coef -> my_type.
在Ocaml
我可以写:
let test_mytype := function
| Mytype_ex1 [Mytype_coef (Mycoef_ex2 (My_matrix m)); Mytype_int i] :: ps -> ...
我想在我的函数需要两个参数的同一函数中使用参数m
和i
。但是在Coq
我不能这样做,例如,如果我写入{{ 1}}
Coq
我收到了一个错误:
Definition test_mytype (m: my_type) :=
match m with
| Mytype_ex1 (Mytype_coef (Mycoef_ex2 (My_matrix m)))
| Mytype_int i :: ps => my_function m i
...
end.
如果我写下这个功能,Toplevel input, characters 82-215:
Error: The components of this disjunctive pattern must bind the same variables.
会被接受,但我不能同时使用Coq
和m
i
我也尝试使用匹配例如:
Definition test_mytype (m: my_type) :=
match m with
| Mytype_ex1 (Mytype_coef (Mycoef_ex2 (My_matrix m))) :: ps => ...
| Mytype_ex1 (Mytype_int i) :: ps => ...
...
end.
但我的问题是Definition test_mytype (m1, m2: my_type) :=
match m1, m2 with
| Mytype_ex1 (Mytype_coef (Mycoef_ex2 (My_matrix m))) :: ps,
| Mytype_ex1 (Mytype_int i) :: ps => ...
...
end.
和m
应该属于同一个i
。
您知道如何在m: my_type
中同时编写可同时使用test_mytype
和m
的函数i
吗?
答案 0 :(得分:6)
您似乎没有很好地掌握析取模式的内容。
我们假设,例如,我在OCaml中定义了一个类型either
:
type either = Left of int | Right of int
因此,either
类型的值只是标有Left
或Right
的整数。
我现在可以编写的一个明显的函数是int_of_either
,它将either
类型的值作为其参数,并生成一个整数作为结果:
let int_of_either = function
| Left x -> x
| Right x -> x
现在,请注意Left
和Right
的案例具有相同的右侧。在这种情况下,析取模式允许我通过使模式匹配的两个臂共享一个右侧来使我的函数更简洁:
let int_of_either = function
| Left x
| Right x -> x
当然,只有在两种模式中绑定变量x
时才能解决这个问题。 (此外,绑定应该是一致的,因为它们应该就x
的类型达成一致。这里,它们都会将x
绑定到类型int
的值。)
也就是说,如果我写,例如
let int_of_either = function
| Left x
| Right y -> y
编译器将拒绝我的程序并抱怨y
Left
没有发生either
:
错误:变量y必须出现在此|的两侧图案
以类似的方式,如果在Coq中我定义了类型Inductive either :=
| Left : Z -> either
| Right : Z -> either.
int_of_either
和一个函数Definition int_of_either (e : either) : Z :=
match e with
| Left x => x
| Right x => x
end.
int_of_either
然后我可以使用析取模式将Definition int_of_either (e : either) : Z :=
match e with
| Left x
| Right x => x
end.
重写为
Definition int_of_either (e : either) : Z :=
match e with
| Left x
| Right y => y
end.
但是,如果我写
{{1}}
编译器抱怨
错误:此析取模式的组件必须绑定相同的变量。
这正是你得到的错误。
总之,我建议暂时忘记析取模式,并首先尝试使用专用右侧为模式匹配的每个臂定义函数,然后再考虑是否可以稍微编写函数紧凑的形式。
答案 1 :(得分:2)
match m with
| Mytype_ex1 (Mytype_coef (Mycoef_ex2 (My_matrix m)))
| Mytype_int i :: ps
=> my_function m i
错了,不能工作。不仅第一个匹配my_type
和。{
第二个my_type list
,但是以析取模式(或模式)
双方必须捕获相同的变量:它没有意义
在案例中定义m
,在另一个案例中定义i
,并期望两者都成立
在分支中定义。
所以我不知道你要做什么,但Coq和OCaml有 这里的限制相同,并且应该没有区别。