The future 4.03 release of OCaml has added a new warning, 57
, to prevent ambiguous guarded pattern. Namely, the issue is that on an or-pattern with a when
clause, if the first part of the or-pat matches, but the when
evaluates to false
, the complete pattern will be discarded, although another variant of the or-pat could have succeed. For instance, on the following code, ko
will be bound to 1
, which can be surprising:
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")
In 4.03, OCaml will complain with Warning 57: Ambiguous guarded pattern, variable s may match different or-pattern arguments
, suggesting you to check whether you really intended this behavior or not.
However, the warning is also active on the second line of the pattern matching in the following definition:
let f x y =
match x,y with
| A _, A _ -> 0
| A s, _ | _, A s when s = "foo" -> 1
| _ -> 2
Here, I'd argue that the ambiguity cannot arise, since A _, A _
is matched by the first line, hence at most one of the components of the or-pattern can match if the program gets to this point. Is this reasoning correct?
If the answer is yes, I would like to know in addition whether it is possible to silence this warning on this specific branch. Indeed, I can do match [@warning "-57"] x,y with
, but this will silence the warning if someone introduces another ambiguous pattern there sometime later. I've tried to put the attribute at the pattern level (| A s, _ | _, A s [@warning "-57"] when s = "foo"
), but this has no effect.
NB: I know that in this specific case I could just replace the catch-all with | A s, B _ | B _, A s when s = "foo"
to make the ambiguity disappear, but consider that this is only a reduced example.