Using User Defined Fixity

Users can define custom fixity for names/symbols. The scope of fixity definition is within the same file.

The keywords are infix, infixl, infixr, prefix, postfix and nonfix.


extern fun add (int, int): int
symintr ~>
symintr >>

infix  ~>         (* make ~> infix, non-assoc *)
infixl ~> add     (* make ~> and `add` infix, left-assoc *)
infixl (+) ~> >>  (* make ~> and >> infix, left-assoc, 
                     having the same precedence as (+) 
                     note that this name/symbol as to be in 
                     parenthesis in order to be parsed as a
                     precedence definition *)
infixr 50  ~> >>  (* make ~> and >> infix, right-assoc, 
                     having precedence 50. *)
postfix (= + 1) ^ (* make ^ postfix, having the same
                     precedence as (=) plus 1. 
                     note that the `+` need to be separated 
                     from `=`, or it will be parsed as part
                     of the symbol *)
nonfix add        (* make `add` nonfix, which means it can only
                     be used as functions from this point on. *)

Roughly speaking the syntax is as follows. (In a BNF-like syntax)

keyword    ::= "infix" | "infixl" | "infixr" | "postfix" | "prefix"
opr        ::= symbol | name
precedence ::= number | "(" opr (("+"|"-") number)? ")"

fixity     ::= keyword precedence? opr+ | "nonfix" opr+

In addition, users can change fixity temporarily using the following syntax.

  • change a name to infix, non-assoc: name(a,b) => a \name b
  • change a symbol to prefix: a + b => op+ (a, b)