There seem to be a number of symbols that can act as infix operators; e.g.
(+)
, (-)
, (*)
, (/)
, mod
(+.)
, (-.)
, (*.)
, (/.)
(=)
, (<>)
, (<)
, (<=)
, (>)
, (>=)
(|>)
, (<<)
, (>>)
(>>=)
, (>>|)
(::)
, (@)
(^)
, (^/)
, (^:)
What determines whether a function can act as an infix operator or not?
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