(Introduced in 4.08.0)
|
Binding operators offer syntactic sugar to expose library functions under (a variant of) the familiar syntax of standard keywords. Currently supported “binding operators” are let<op> and and<op>, where <op> is an operator symbol, for example and+$.
Binding operators were introduced to offer convenient syntax for working with monads and applicative functors; for those, we propose conventions using operators * and + respectively. They may be used for other purposes, but one should keep in mind that each new unfamiliar notation introduced makes programs harder to understand for non-experts. We expect that new conventions will be developped over time on other families of operator.
Users can define let operators:
and then apply them using this convenient syntax:
which is equivalent to this expanded form:
Users can also define and operators:
to support the syntax:
which is equivalent to this expanded form:
An applicative functor should provide a module implementing the following interface:
where (let+) is bound to the map operation and (and+) is bound to the monoidal product operation.
A monad should provide a module implementing the following interface:
where (let*) is bound to the bind operation, and (and*) is also bound to the monoidal product operation.
The form
let<op0> x1 = e1 and<op1> x2 = e2 and<op2> x3 = e3 in e
desugars into
( let<op0> ) (( and<op2> ) (( and<op1> ) e1 e2) e3) (fun ((x1, x2), x3) -> e)
This of course works for any number of nested and-operators, but the fully general rule is inconvenient to express and hard to read.
Note that the grammar allows mixing different operator symbols in the same binding (<op0>, <op1>, <op2> may be distinct), but we strongly recommend APIs where let-operators and and-operators working together use the same symbol.
(Introduced in 4.13.0)
When the expression being bound is a variable, it can be convenient to use the shorthand notation let+ x in ..., which expands to let+ x = x in .... This notation, also known as let-punning, allows the sum3 function above can be written more concisely as:
This notation is also supported for extension nodes, expanding let%foo x in ... to let%foo x = x in .... However, to avoid confusion, this notation is not supported for plain let bindings.