Search code examples
ats

How do you pattern-match against negative 1?


This fails with "the pattern is expected to be formed with a constructor (of datavtype)", as it's matching the special free()ing syntax for linear constructors rather than the negative sign.

#include "share/atspre_staload.hats"
implement main0() =
        case ~1 of
        | ~1 => println!("ok")
        | _ => ()

This fails with "operator fixity cannot be resolved". It doesn't help to add parens or to make a binary operator.

#include "share/atspre_staload.hats"
implement main0() =
        case ~1 of
        | -1 => println!("ok")
        | _ => ()

This fails as the variable in the case introduces a new binding, unrelated to the binding already in scope:

#include "share/atspre_staload.hats"
implement main0() =
        let
                val negative_one = ~1
        in
                case ~2 of
                | negative_one => println!("unintend match")
                | _ => () // error: this pattern match clause is redundant
        end

Is this the closest we can get? How much less performant is it?

#include "share/atspre_staload.hats"
implement main0() =
        let
                val negative_one = ~1
        in
                ifcase
                | negative_one = ~1 => println!("this works")
                | _ => ()
        end

Solution

  • In ATS, ~1 is not considered a constant; it is a function application: ~ being applied to 1. You can define negative 1 as follows:

    #define NEG1 %(~1) // not yet working // to be fixed
    

    or

    #define NEG1 %(0-1) // this one is currently working
    

    Then you can write:

    case ~1 of
    | 1 => ...
    | NEG1 => ...
    

    Using 'ifcase' (instead of 'case') should be equally efficient.