Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Types

Type Expressions

Erlang comes with a variety of builtin types.

With Tele parentheses are optional for type expressions. For example the integer type can be represented like this:

integer()

OR

integer

Type Parameters

Some types can take other types as parameters for more specificity. For example the list type:

list

Can be more specific to be a list of integers:

list(integer)

Type Definitions

In tele we can define our own types:

type point: #(integer, integer)

This defines a type called point that is a tuple with two integers.

We can use it in a a function spec.

spec move_up(point): point
fun move_up(#(x, y)): #(x, y - 1)

Private Type Definitions

Types are exported from the module by default. Use typep if you do not want the type to be exported.

typep internal_id: integer

Type Variables

Since Tele uses lowercase letters for both types and variables it can make type variables ambiguous. This is solved by using an absolute variable.

Let's see how we can define a type with a type variable and use it.

Let's make a result type like so:

type result(@data): #('ok, @data) | #('error, any)

This is a type that can either be an ok tuple with some specified type or an error tuple with any type.

Let's see how we can use it for a function spec:

spec some_api_call(): result(list(map))
fun some_api_call():
  call_some_api()

Here we are specifying that the function some_api_call will return an okay tuple with a list of maps or an error tuple.

Nominal Types

As of Erlang 28, nominal types are supported. Nominal types are user-defined types that are distinguished by their name, not their structure.

In Tele a nominal type definition looks like this:

nominal id: integer

Now function definitions like this would fail a type check:

spec add2(integer): integer
fun add2(a): a + 2

spec get_todo(id): map
fun get_todo(id): ...

fun get_todo2():
  get_todo(add2(0))

get_todo(add2(0)) would fail the type check because get_todo accepts an id as an input not an integer.