Lei Wu
Lei Wu

Reputation: 70

Pattern matching against List variable

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

Answers (2)

psfinaki
psfinaki

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

AMieres
AMieres

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

Related Questions