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.