FStar icon indicating copy to clipboard operation
FStar copied to clipboard

Cannot match on negative integer literals

Open mgritter opened this issue 3 years ago • 2 comments

There doesn't seem to be a way to match on a negative integer. Here's a small reproduction:

module ExampleMatch

let sign = (z:int{z = 0 \/ z = (-1) \/ z = 1})

let example_1 (s:sign) : string =
 match s with
 | (-1) -> "negative"
 | 1 -> "positive"
 | 0 -> "zero"

There is a syntax error in the -1 case, with or without parentheses.

I initially ran into this case while trying to use an optional sign so Some (-1) has the same problem.

mgritter avatar Dec 28 '21 07:12 mgritter

Workaround:

let example_3 (s:sign) : string =
 match s with
 | v when v = (-1) -> "negative"
 | 1 -> "positive"
 | 0 -> "zero"

I'm not sure in what contexts the "match ... when" syntax is supported. I've gotten the error "When clauses are not yet supported in --verify mode; they will be some day" when I attempted to use it previously, so it's not clear what is OK and what isn't.

For example, we can't match on a option sign in this way, that triggers the "not yet supported" error.

mgritter avatar Dec 28 '21 19:12 mgritter

It is a parser issue, negative int literals are not supported as patterns in the parser.

As a workaround, you could also use if then else:

let example_1 (s:sign) : string =
  if s = -1 then "n"
  else if s = 1 then "p"
  else begin
    assert (s == 0); //not necessary, just for illustration
    "z"
  end

let example_2 (s:option sign) : string =
  match s with
  | None -> "none"
  | Some s -> example_1 s

when clauses are not yet supported for all practical purposes. (The typechecker has an internal "lax" mode of operation that does not verify code, that's where when may be used.)

aseemr avatar Dec 29 '21 05:12 aseemr