15

I have this simple F# function:

let compareNum x =
    let y = 10
    match x with
    | _ when x = y -> 0
    | _ when x > y -> 1
    | _ when x < y -> -1

However, F# compiler gives me "Incomplete pattern matches on this expression" warning. In this case, all cases should cover every pattern.

I also see a similar example in "Pattern Matching" section in the 1st edition of Programming F# book by Chris Smith. So something might be changed in the later version of F#?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
kimsk
  • 2,221
  • 22
  • 23
  • 10
    The compiler assumes that any code with `when` guards is an incomplete match. It is inelegant, and produces false positives like you saw. – John Palmer Sep 09 '13 at 04:57
  • possible duplicate of [Incomplete pattern matching a tuple in F#](http://stackoverflow.com/questions/11354156/incomplete-pattern-matching-a-tuple-in-f) – John Palmer Sep 09 '13 at 04:58
  • 2
    Thanks! I like how one of the answer in the above question said, "In general, it is an anti-pattern to have a when guard in the last pattern." I think that makes sense now. – kimsk Sep 09 '13 at 05:09
  • 4
    This is one of those cases where using "if" is not only more idiomatic--it's also a far better way to code the test. – Onorio Catenacci Sep 09 '13 at 16:56

1 Answers1

19

I think the answer to the previous question (and the comments -- "In general, it is an anti-pattern to have a when guard in the last pattern" -- by kimsk) explain the situation.

However, I would not say that having a guard in the last pattern is an anti-pattern - it is the easiest workaround, but I find this somewhat unfortunate, because the when pattern gives you useful information about the values you can expect - and that makes understanding the program easier. Last time I had this problem, I left it there, at least as a comment:

let compareNum x =
  let y = 10
  match x with
  | _ when x = y -> 0
  | _ when x > y -> 1
  | _ (*when x < y*) -> -1
Community
  • 1
  • 1
Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • 2
    +1, if you had the equality check `-> 0` as the final pattern it might go some way towards preserving readability without the comment - but personally I think I like this better. – MattDavey Sep 09 '13 at 14:50