Is it possible to do pattern matching on variables instead of constant values:
# let x = 2 in
let y = 5 in
match 2 with
| x -> "foo"
| y -> "bar"
| _ -> "baz";;
let y = 5 in
Warning 26: unused variable y.
let x = 2 in
Warning 26: unused variable x.
| y -> "bar"
Warning 11: this match case is unused.
| _ -> "baz";;
Warning 11: this match case is unused.
- : string = "foo"
Obviously, with this syntax, the x -> "foo"
case takes everything. Is there a way to make it be equivalent to:
match 2 with
| 2 -> "foo"
| 5 -> "bar"
| _ -> "baz"
where the values of the match expressions are determined at runtime?
A when
guard is a bad idea here in my opinion. Beginners tend to over-use the pattern-matching syntax that they find convenient, and this result in subtle bugs in their application. For one person that will notice that "hey, | y -> ..
here is not what I want", ten other persons will make the mistake and don't notice it directly.
You should discourage such error-prone pattern. My personal advice to beginners is to never use when
, and to only use pattern-matching to destructure values of an inductive datatype (such as lists, trees, options, etc.). Pattern-matching on integers is almost always a mistake.
I recommend to use if ... then .. else if .. then .. else
instead.
if z = x then "foo"
else if z = y then "bar"
else "baz"
When is it legitimate to use when
? It is understandable to have one when the rest of the cases do benefit from pattern-matching (to test nested patterns, etc.), or when the test is performed on values resulting from deep destructuration of the matched value. It can often be translated away by merging two branches and using an if..then..else
locally.
One exampe where it is inconvenient to remove is the following (testing combined to destructuring):
match foo with
| (Baz x) when pred x -> ...
| _ -> ...
You need when
guard:
let x = 2 in
let y = 5 in
match 2 with
| z when z = x -> "foo"
| z when z = y -> "bar"
| _ -> "baz";;
The error messages are very instructive. When you use:
let x = 2 in
...
match 2 with
| x -> "foo"
| ...
the new value x
shadows the value x
in previous let-bound hence the first error message. Moreover, since the new x
matches everything, two below patterns of y
and _
are obviously redundant.
Note that matching a constant (match 2 with
) is not a good idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With