Search code examples
ocamlinfix-notationinfix-operator

What are the legal names for infix operators?


There seem to be a number of symbols that can act as infix operators; e.g.

  • ints: (+), (-), (*), (/), mod
  • floats: (+.), (-.), (*.), (/.)
  • comparison: (=), (<>), (<), (<=), (>), (>=)
  • functions: (|>), (<<), (>>)
  • monads: (>>=), (>>|)
  • lists: (::), (@)
  • misc: (^), (^/), (^:)

What determines whether a function can act as an infix operator or not?


Solution

  • It's determined by the first symbol of the operator. From the manual:

    infix-symbol    ::= (= ∣  < ∣  > ∣  @ ∣  ^ ∣  | ∣  & ∣  + ∣  - ∣  * ∣  / ∣  $ ∣  %) { operator-char }  
        ∣    # { operator-char }+  
    
    prefix-symbol   ::= ! { operator-char }  
        ∣    (? ∣  ~) { operator-char }+  
    
    operator-char   ::= ! ∣  $ ∣  % ∣  & ∣  * ∣  + ∣  - ∣  . ∣  / ∣  : ∣  < ∣  = ∣  > ∣  ? ∣  @ ∣  ^ ∣  | ∣  ~
    

    So, for example, a custom operator defined like this:

    let (@?) a b = ...
    

    Would be considered an infix operator since it starts with @, while

    let (?@) a b = ...
    

    is a prefix operator because it starts with ?.

    There are some additions and exceptions to this, however, described in the manual here:

    • mod, land, lor, lxor, lsl, lsr and asr are keywords treated as infix operators (e.g. 2 mod 4).

    • - and -. can be interpreted as either infix or prefix operators. When prefix thay are translated to ~- and ~-. respectively.

    • && and || are also treated specially, for reasons. See the comments by @octachron below for a bit more of an explanation.

    Lastly, you might also want to consider precedence and associativity, which is listed in the table near the top, before the first section here