Skip to content

Functions

Functions are values. Write a function type as fn(A) -> R. Named functions always annotate parameters and results. A lambda uses =>. Skip lambda parameter types only when the expected type already supplies them.

|> passes the left-hand side as the first argument of the call on the right. List<A> is a linked list of one element type. gale_std.stream is a lazy Elixir stream, not a list. map and take stay lazy until to_list.

mod functions
alias gale_std.stream
pub fn prepend(head: Integer, tail: List<Integer>) -> List<Integer> {
[head | tail]
}
pub fn sum(items: List<Integer>) -> Integer {
case items {
[] -> 0
[head | tail] -> head + sum(tail)
}
}
fn add(n: Integer, amount: Integer) -> Integer {
n + amount
}
fn twice(n: Integer) -> Integer {
n * 2
}
pub fn scale(n: Integer) -> Integer {
n
|> add(5)
|> twice()
|> add(1)
}
pub fn run(f: fn(Integer) -> Integer, n: Integer) -> Integer {
f(n)
}
pub fn inc(n: Integer) -> Integer {
run(fn(x) -> x + 1, n)
}
pub fn first_n(values: List<Integer>, n: Integer) -> List<Integer> {
values
|> stream.from_list()
|> stream.map(fn(value: Integer) -> value * 2)
|> stream.take(n)
|> stream.to_list()
}

Functions can call themselves or other functions declared later in the same module. Use gale_std.list for eager list operations and gale_std.stream for lazy processing. Convert a stream to a list when you need to collect its results. The next chapter, proving, adds contracts that gale verify can check.