Reputation: 70
Why does the second pattern matching return "1 and 2" and give me a warning "This rule will never be matched" on the wildcard _?
let a = [3;4]
match a with
|[1;2] -> "1 and 2"
|_ -> "Other"
|> printfn "%A"
let lst = [1;2]
match a with
|lst -> "1 and 2"
|_ -> "Other"
|> printfn "%A"
It appears to me lst is considered truthy. How so?
Upvotes: 2
Views: 96
Reputation: 2132
In your 2nd pattern matching you have two different lst
variables with the same name. Here,
let lst = [1;2]
match a with
| lst -> "1 and 2"
| _ -> "Other"
in the 1st match case you don't refer to the lst
variable above, you create a new one. You can check it by trying to refactor-rename it (F2 in Visual Studio). As AMieres explains, case is important.
In general, referring to a variable in a match case is doable yet not trivial. Consider this code:
let helloWorld = "hello world"
let isHelloWorld s =
match s with
| helloWorld -> true
| _ -> false
Here you will get the same warning as described. One way to go is to mark the constant with the [<Literal>]
attribute and to make it upper-case at the same time:
[<Literal>]
let HelloWorld = "hello world"
let isHelloWorld s =
match s with
| HelloWorld -> true
| _ -> false
This would work as expected. However, you can apply the [<Literal>]
attribute only to certain types, and list is not among them. For those, you have to leverage when
conditions in match cases.
Upvotes: 1
Reputation: 5004
An identifier in lowercase matches with everything and binds the identifier to the value.
If you want to compare lst
with a
you need to use when
which is a conditional guard:
let a = [3;4]
match a with
|[1;2] -> "1 and 2"
|_ -> "Other"
|> printfn "%A"
let lst = [1;2]
match a with
| b when b = lst -> "1 and 2"
|_ -> "Other"
|> printfn "%A"
but in this case a simple if then else
would work.
Upvotes: 3