Veila

Types

Type parameters

If a type has type parameters, they are enclosed in square brackets. If the name of a type parameter is unbound, it is a type variable. Otherwise, it is treated as a type argument.

Examples:

max ← # (numbers: list[integer]): integer – integer is a bound type


first ← # (items: list[item-type]): optional[item-type] – item-type is a variable

Like with regular variables, type parameters can also shadow existing names by having an ! in the front:

some-weird-function ← # (items: list[!string]): string – string is a variable

Generic parameters are enclosed in brackets by themselves:

identity ← # (item: [item-type]): [item-type] item

Function types

Function types have the syntax #(parameter-types → return-type). For example:

fold ← #
   (items: list[input-type],
    initial-state: [state-type],
    folder: #([state-type], [input-type] → [state-type]))
   : [state-type]

Named parameters

It’s possible for a function type to have named parameters, which allows functions that are passed as parameters to be called with named arguments. For example:

folder: #(state: [state-type], next: [input-type] → [state-type])
– To call this function:
folder(state: …, next: …)

In this case, the function that’s passed in must support the required named parameters. Thus, the folder parameter needs to be passed a function of the form # (state, next) …. If this causes name clashes, then the parameters can be simply declared as shadowing or be declared as labels (i.e. # (state acc, !next) …).