I wrote this for the Arena Tech Blog but I'm cross-posting it here.


One of the hardest parts of learning OCaml is figuring out what the infix operators do, since they're just a string of symbols and you can't find them with a Google search. This is my attempt to make a cheatsheet for whenever you're wondering what a random series of symbols means. Doing a search on this page should find basic info about any of the common OCaml operators.

Note that some libraries define their own operators, like how Jane Street's Command.Spec defines ++, +>, and +<. In cases like that, hopefully the library you're using will make it clear what the infix operators do.

General info about infix functions

In OCaml, a function is infix if its name starts with one of these characters:

= @ ^  & + - * / $ %

Followed by zero or more of these characters:

! $ % & * + - . / : ? @ ^  ~

When defining an infix function, you need to put () around the "name".

For example, in utop:

# let (=<>@^|&~+-*/$%!?:.) a b =
a + b ;;  
val ( =<>@^|&~+-*/$%!?:. ) : int -> int -> int = <fun>

# 1 =<>@^|&~+-*/$%!?:. 2 ;;
- : int = 3

Also, you can see the type of an infix operator in utop by again wrapping the function name in parentheses:

# (=<>@^|&~+-*/$%!?:.);;
val ( =<>@^|&~+-*/$%!?:. ) : int -> int -> int = <fun>

The official documentation for this is here, although this blog has a more accessible explanation.

Built-in infix operators

The built-in operators are defined in Pervasives:

Refer to the documentation for the magic involved in functions that work on multiple types (=, <>, <, >, etc).

Operator Description
= Structural equality[1]
<> Structural inequality[1]
< Less than
> Greater than
<= Less than or equal
>= Greater than or equal
== Physical equality (same object)[1]
!= Physical inequality (not same object)[1]
&& Boolean and
& (Deprecated) Boolean and
|| Boolean or
| (Deprecated) Boolean or
|> Reverse function application (x |> f is the same as f x)
@@ Function application (f @@ x is the same as f x)
~- Integer negation (same as unary -)
~+ Described as "unary addition" but doesn't seem to do anything.
+ Integer addition
- Integer subtraction
* Integer multiplication
/ Integer division
~-. Float negation (same as unary -.)
~+. Described as "unary addition" but doesn't seem to do anything.
+. Float addition
-. Float subtraction
*. Float multiplication
/. Float division
** Float exponentiation
^ String concatenation
@ List concatenation
! Get the value of a ref
:= Set the value of a ref
^^ Format string concatenation

Jane Street

Numbers

Jane Street generally defines arithmetic operators in modules where they make sense, so you can do things like:

Bigint.(of_int 1 + of_int 3 / of_int 5)

The documentation for this interface is under Int_intf.S_common, although most of them are defined for floating point numbers too.

Operator Description
+ Module-specific addition (i.e. Float.(+) is float addition)
- Module-specific subtraction
* Module-specific multiplication
/ Module-specific division
// Integer division return float
% Infix mod (result is always positive)
/% Infix mod (result is negative if the input is negative)

Monads

Jane Street's libraries (Core, Async, Base, etc.) consistently define infix operators under Monad_infix modules.

Operator Description
>>= Infix version of bind. Opening Async sets this to Deferred.bind
>>| Infix version of map. Opening Async sets this to Deferred.map
>>=? bind mixed with Or_error. Opening Async sets this to Deferred.Or_error.bind
>>|? map mixed with Or_error. Opening Async sets this to Deferred.Or_error.map

map and bind are documented assuming that you're familiar with monads, and you may find this StackOverflow answer useful if you need more information.

>>= and >>| show up most commonly in Async, but they can also be used with Option, List, Result, etc.

Lwt

See the Lwt documentation.

Operator Description
>>= Infix version of bind
=<< bind with the arguments reversed
>|= Infix version of map. Same as >>| in Jane Street code
=|< map with the arguments reversed

Lwt doesn't have Async's >>=? or >>|? because Lwt.t can contain errors without having a separate Or_error module.

See the Jane Street Monad section above if you need info about map and bind actually do.