Current section

Files

Jump to
lfe doc man lfe_types.7
Raw

doc/man/lfe_types.7

'\" t
.\" Automatically generated by Pandoc 3.3
.\"
.TH "lfe_types" "7" "2021" ""
.SH NAME
lfe_types \- LFE Types and Functions Specifications
.SH TYPES
This is a description of the type syntax.
.PP
.TS
tab(@);
l l.
T{
LFE type
T}@T{
Erlang type
T}
_
T{
\f[CR](any)\f[R]
T}@T{
\f[CR]any()\f[R]
T}
T{
\f[CR](none)\f[R]
T}@T{
\f[CR]none()\f[R]
T}
T{
\f[CR](atom)\f[R]
T}@T{
\f[CR]atom()\f[R]
T}
T{
\f[CR](integer)\f[R]
T}@T{
\f[CR]integer()\f[R]
T}
T{
\f[CR](range i1 i2)\f[R]
T}@T{
\f[CR]I1..I2\f[R]
T}
T{
\f[CR](float)\f[R]
T}@T{
\f[CR]float()\f[R]
T}
T{
\f[CR](bitstring m n)\f[R]
T}@T{
\f[CR]<<_:M,_:_*N>>\f[R]
T}
T{
\f[CR](binary)\f[R]
T}@T{
\f[CR]<<_:0,_:_*8>>\f[R]
T}
T{
\f[CR](bitstring)\f[R]
T}@T{
\f[CR]<<_:0,_:_*1>>\f[R]
T}
T{
\f[CR](nil)\f[R]
T}@T{
\f[CR][] %% nil\f[R]
T}
T{
\f[CR]...\f[R]
T}@T{
\f[CR]...\f[R]
T}
T{
\f[CR](lambda any <type>)\f[R]
T}@T{
\f[CR]fun((...) \-> <type>)\f[R]
T}
T{
\f[CR](lambda () <type>)\f[R]
T}@T{
\f[CR]fun(() \-> <type>)\f[R]
T}
T{
\f[CR](lambda (<tlist>) <type>)\f[R]
T}@T{
\f[CR]fun((<tlist>) \-> <type>)\f[R]
T}
T{
\f[CR](map)\f[R]
T}@T{
\f[CR]map()\f[R]
T}
T{
\f[CR]#M()\f[R]
T}@T{
\f[CR]#{}\f[R]
T}
T{
\f[CR]#M(<key> <value> ...)\f[R]
T}@T{
\f[CR]#{<pairlist>}\f[R]
T}
T{
\f[CR](tuple)\f[R]
T}@T{
\f[CR]tuple()\f[R]
T}
T{
\f[CR]#()\f[R]
T}@T{
\f[CR]{}\f[R]
T}
T{
\f[CR]#(<tlist>)\f[R]
T}@T{
\f[CR]{<tlist>}\f[R]
T}
T{
\f[CR](UNION <tlist>)\f[R]
T}@T{
\f[CR]<type> | <type>\f[R]
T}
.TE
.PP
Apart from the predefined types in the Erlang type system we also have
the following predefined types which cannot be redefined:
\f[CR]UNION\f[R], \f[CR]call\f[R], \f[CR]lambda\f[R] and
\f[CR]range\f[R].
The usage of \f[CR]bitstring\f[R], \f[CR]tuple\f[R] and \f[CR]map\f[R]
have also been extended.
.PP
Note that the type \f[CR]#M()\f[R] is the empty map and the type
\f[CR]#()\f[R] is the empty tuple.
We can still use the older \f[CR](map <key valuelist>)\f[R] and
\f[CR](tuple <tlist>)\f[R] formats when declaring types for maps and
tuples.
.PP
The general form of bitstrings is \f[CR](bitstring m n)\f[R] which
denotes a bitstring which starts with \f[CR]m\f[R] bits and continues
with segments of \f[CR]n\f[R] bits.
\f[CR](binary)\f[R] is a short form for a sequence of bytes while
\f[CR](bitstring)\f[R] is a short form for a sequence of bits.
There is currently no short form for an empty binary,
\f[CR](bitstring 0 0)\f[R] must be used.
.SS Type Declarations of User\-Defined Types
\f[B]\f[CB](deftype (type\-name) type\-def)\f[B]\f[R]
.PP
\f[B]\f[CB](defopaque (type\-name) type\-def)\f[B]\f[R]
.PP
\f[B]\f[CB](deftype (type\-name par1 par2) type\-def)\f[B]\f[R]
.PP
\f[B]\f[CB](defopaque (type\-name par1 par2) type\-def)\f[B]\f[R]
.PP
For unparameterised types the parentheses around the type name are
optional.
An example:
.IP
.EX
(deftype foo (tuple \[aq]foo (integer) (list)))
(deftype bar (tuple \[aq]bar (integer) (list)))
.EE
.SS Type Information in Record Declarations
\f[B]\f[CB](defrecord rec (field1 default1 type1) (field2 default2) (field3))\f[B]\f[R]
.PP
Fields with type annotations \f[I]MUST\f[R] give a default value and
fields without type annotations get the default type \f[CR](any)\f[R].
.SH SPECIFICATIONS
.SS Type specifications of User\-Defined Functions
\f[B]\f[CB](defspec (func\-name arity) function\-spec ...)\f[B]\f[R]
.PP
where
.IP
.EX
function\-spec = (arg\-type\-list ret\-type)
function\-spec = (arg\-type\-list ret\-type constraint\-list)
function\-spec = #M(arg\-types arg\-type\-list ret\-type ret\-type)
function\-spec = #M(arg\-types arg\-type\-list ret\-type ret\-type
contraints constraint\-list)
arg\-type\-list = (arg\-type ...)
constraint\-list = (constraint ...)
constraint = (var var\-type)
.EE
.PP
For multiple types add more function specs.
The parentheses around the function name and the arity are optional.
For example from the docs:
.IP
.EX
(defspec foo ([(pos_integer)] (pos_integer)))
(defspec (foo 1)
([(pos_integer)] (pos_integer))
([(integer)] (integer)))
(defspec (remove\-if 2)
([(lambda ((any)) (boolean)) (list)] (list)))
.EE
.PP
Or with constraints:
.IP
.EX
(defspec id ((X) X ((X (tuple)))))
(defspec (foo 1)
([(tuple X (integer))] X ((X (atom))))
([(list Y)] Y ((Y (number)))))
(defspec (remove\-if 2)
([pred (list)] (list) [(pred (lambda ((any)) (boolean)))]))
.EE
.PP
Note that a constraint variable doesn\[cq]t need to start with an
upper\-case like an Erlang variable, though in some case it may be
easier to read.
.PP
Note we are using the alternate list form with \f[CR][ ]\f[R] instead of
parentheses to make it easier to see the function arguments.
.SH Types and function specifications in the module definition
Types can also be defined in the module declaration, for example:
.IP
.EX
(defmodule this\-module
...
(type ((foo\-type) (tuple \[aq]foo (integer) (list)))
((bar\-type) (tuple \[aq]bar (integer) (list))))
(spec ((foo 1) ([(integer)] (foo\-type)))
((id 1) ([x] x ((x (tuple))))))
...)
.EE
.SH AUTHORS
Robert Virding.