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.Spec1 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".
# 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 here3, although this blog4 has a more accessible explanation.
Built-in infix operators
The built-in operators are defined in Pervasives5:
Refer to the documentation for the magic involved in functions that work on multiple types (=, <>, <, >, etc).
| Operator | Description |
|---|---|
= | Structural equality[16] |
<> | Structural inequality[16] |
< | Less than |
> | Greater than |
<= | Less than or equal |
>= | Greater than or equal |
== | Physical equality (same object)[16] |
!= | Physical inequality (not same object)[16] |
&& | 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_common7, 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 mod8 (result is always positive) |
/% | Infix mod8 (result is negative if the input is negative) |
Monads
Jane Street's libraries (Core, Async, Base, etc.) consistently define infix operators under Monad_infix modules9.
| Operator | Description |
|---|---|
>>= | Infix version of bind10. Opening Async sets this to Deferred.bind11 |
>>| | Infix version of map. Opening Async sets this to Deferred.map12 |
>>=? | bind mixed with Or_error. Opening Async sets this to Deferred.Or_error.bind13 |
>>|? | map mixed with Or_error. Opening Async sets this to Deferred.Or_error.map14 |
map and bind are documented assuming that you're familiar with monads15, and you may find this StackOverflow answer16 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 documentation17.
| Operator | Description |
|---|---|
>>= | Infix version of bind10 |
=<< | 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.
https://ocaml.janestreet.com/ocaml-core/latest/doc/core/Core/Command/Spec/index.html#val-(++)
https://github.com/diml/utop - "GitHub - ocaml-community/utop: Universal toplevel for OCaml"
https://caml.inria.fr/pub/docs/manual-caml-light/node4.9.html - "Infix symbols"
https://haifengl.wordpress.com/2014/07/02/ocaml-functions/ - "OCaml: Functions | Haifeng's Random Walk"
https://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html
https://stackoverflow.com/a/13596236/212555
https://ocaml.janestreet.com/ocaml-core/latest/doc/base/Base/Int_intf/module-type-S_common/index.html
https://en.wikipedia.org/wiki/Modulo_operation - "Wikipedia: Modulo operation"
https://ocaml.janestreet.com/ocaml-core/latest/doc/base/Base/List/Monad_infix/index.html
https://en.wikipedia.org/wiki/Monad_(functional_programming)#Overview - "Wikipedia: Monad (functional programming)"
https://ocaml.janestreet.com/ocaml-core/latest/doc/async_kernel/Async_kernel/Deferred/index.html#val-bind
https://ocaml.janestreet.com/ocaml-core/latest/doc/async_kernel/Async_kernel/Deferred/index.html#val-map
https://ocaml.janestreet.com/ocaml-core/latest/doc/async_kernel/Async_kernel__/Deferred_or_error/index.html#val-bind
https://ocaml.janestreet.com/ocaml-core/latest/doc/async_kernel/Async_kernel__/Deferred_or_error/index.html#val-map
https://en.wikipedia.org/wiki/Monad_(functional_programming) - "Wikipedia: Monad (functional programming)"
https://stackoverflow.com/questions/29851449/what-is-the-use-of-monads-in-ocaml/29852213#29852213
http://ocsigen.org/lwt/3.1.0/api/Lwt - "Module Lwt"