This is probably simple but can someone explain why the following pattern matching is not sensible? It says other rules e.g. 1, 0, _ will never be matched.
let matchTest(n : int) =
let ran = new Random()
let i = ran.Next(0, 2)
match i with
| n -> printfn "%i" n
| 1 -> printfn "1"
| 0 -> printfn "0"
| _ -> printfn "impossible"
The same thing for this:
let matchTest(n : int) =
let ran = new Random()
let i = ran.Next(0, 2)
let m = n
match i with
| m -> printfn "%i" m
| 1 -> printfn "1"
| 0 -> printfn "0"
| _ -> printfn "impossible"
So why can't it match n
or m
directly here?
The n
in the first example is a place-holder symbol which gets populated if the match succeeds. It's the same as writing:
let matchTest(n : int) =
let ran = new Random()
let i = ran.Next(0, 2)
match i with
| x -> printfn "%i" x
| 1 -> printfn "1"
| 0 -> printfn "0"
| _ -> printfn "impossible"
The symbol x
is populated with the value of i
if the match succeeds, and is then available to use on the right hand side of ->
. This match always succeeds, which explains why the rest of the match cases are unreachable.
In your case, it just so happens that you've named the match variable n
, which is the same name as the input argument.
It's not the same value, though. Instead, what happens is that a new value, also called n
is being created, and the previous n
is no longer accessible.
This is a language feature called shadowing.
You can also see it outside of pattern matching:
let foo n =
let n = 1
n
Example usage:
> foo 42;;
val it : int = 1
> foo 1337;;
val it : int = 1
As you can see, the let-bound n
shadows the input argument n
.
The second example in the OP, where you match on n
is a variation on the first, so the same explanation applies.
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