OCaml的未来版本4.03添加了一个新警告
在4.03版本中,OCaml会报错:
然而,在以下定义中,模式匹配的第二行也会出现相同的警告:
57
,以防止模糊的守卫模式。也就是说,在带有when
子句的或模式中,如果or-pat的第一部分匹配,但when
评估为false
,则完整模式将被丢弃,尽管or-pat的另一个变体可能会成功。例如,在以下代码中,ko
将绑定到1
,这可能令人惊讶:type t = A of string | B of string
let bad x y =
match x,y with
| A s, _ | _, A s when s = "foo" -> 0
| _, _ -> 1
let ok = bad (A "foo") (A "bar")
let ko = bad (A "bar") (A "foo")
在4.03版本中,OCaml会报错:
Warning 57: Ambiguous guarded pattern, variable s may match different or-pattern arguments
,建议您检查是否真的想要这种行为。然而,在以下定义中,模式匹配的第二行也会出现相同的警告:
let f x y =
match x,y with
| A _, A _ -> 0
| A s, _ | _, A s when s = "foo" -> 1
| _ -> 2
在这里,我认为不可能出现歧义,因为A _, A _
会被第一行匹配,因此如果程序到达此点,则至多只能匹配或模式的一个组件。这种推理正确吗?
如果答案是肯定的,我想知道是否可以在特定分支上消除此警告。实际上,我可以使用match [@warning "-57"] x,y with
,但这将在将来某个时候有人再次引入模糊模式时消除警告。我尝试在模式级别上放置属性(| A s, _ | _, A s [@warning "-57"] when s = "foo"
),但这没有效果。
注:我知道在这种特定情况下,我可以用| A s, B _ | B _, A s when s = "foo"
替换catch-all,以消除歧义,但请考虑这只是一个简化的例子。