Functions are defined with
def, where we can also annotate both
the parameter and return types.
def plus2 (x: i32) : i32 = 2 x +
Type inference is supported, so in many cases the types can be left off, in which case the correct type will be inferred from the definition.
def plus2_inferred x = 2 x +
Functions are (almost) first-class values, with the type of a
function from type
a to type
b written as
a -> b. This means
we can write higher-order functions:
def on_i32 (f: i32 -> i32) (x: i32) = f x
When passing an argument to a higher-order function, it is often most practical to use an anonymous function (sometimes called a lambda), like this:
def four = on_i32 (\x -> x + 2) 2
A shortcut notation, called operator sections, allows partial application of infix operators:
def another_four = on_i32 (+2) 2
By enclosing an operator in parentheses we can treat it like any variable name:
def plus = (+)
And we can treat a variable as an infix operator by enclosing it in backticks:
def yet_another_four = 2 `plus` 2
Function values are restricted as follows:
Arrays of functions are not permitted.
A function cannot be returned from an
A loop parameter cannot be a function.
However, it is fine to collect functions in tuples or records.
def fun_tuple : (i32 -> i32, i32 -> i32) = (plus2, plus2_inferred)