为什么在编写这种模式匹配时会出现错误:
type t = A of int | B of float
let f = function
| (A i | B f) -> true
| _ -> false
或
let f = function
| A i | B f -> true
| _ -> false
错误:变量f必须出现在此|的两侧图案
let f = function
| (A i | B i) -> true
| _ -> false
或
let f = function
| A i | B i -> true
| _ -> false
错误:此模式匹配float 类型的int类型的值 但预计会匹配值
的模式
答案 0 :(得分:8)
如果您为多个模式提供单一右侧(就像您一样),OCaml要求模式始终与模式变量绑定。
在第一种情况下,
match ... with
| A i | B f -> ...
...
模式与它们绑定的变量不一致:第一个模式绑定到i
,而第二个绑定到f
。
在第二种情况下,
match ... with
| A i | B i -> ...
...
模式与要绑定到变量的值的类型不一致:第一个模式将类型int
的值绑定到i
,而第二个模式绑定类型{{{ 1}}到float
。
这两种模式可以一致地绑定到变量的唯一方法是不要绑定任何变量:
i
然后完整的例子变成
match ... with
| A _ | B _ -> ...
...
(但请注意,模式匹配的最后一个部分是多余的,因为前两个模式已经详尽地匹配了您的类型type t = A of int | B of float
let f = function
| A _ | B _ -> true
| _ -> false
的所有值。因此,我们得到:
t
这当然等同于写let f = function
| A _ | B _ -> true
。)
答案 1 :(得分:3)
在Or
模式(|
模式)中,您将无法跟踪您所在的构造函数。因此,您需要绑定同一组变量才能工作而无需引用构造函数。
OCaml是强类型的;值i
不能同时具有int
类型和float
类型。
如果类型t
有两种以上的情况,您应该写:
let f = function
| A _ | B _ -> true
| _ -> false
否则:
let f = function
| A _ | B _ -> true
就足够了,因为模式匹配已经很详尽。
我同意Or
模式是相当严格的,但有时在你的函数中有对称的情况时它会很有用:
type num =
| Int of int
| Float of float
let add s1 s2 =
match s1, s2 with
| Int i1, Int i2 -> Int (i1 + i2)
| Int i, Float f | Float f, Int i -> Float (float i +. f)
| Float f1, Float f2 -> Float (f1 +. f2)