Nominal types are new in Erlang/OTP 28: https://www.erlang.org/eeps/eep-0069
Previously the dialyzer considered two types to be the same only if they were structurally equal. For example {number(), number()}
created in one place is equivalent to any other {number(), number()}
with structural typing. With nominal typing two types are considered the same only if their type has the same name. In Erlang this means that you have functions with spec
s that say they return a type defined with -nominal Type :: Definition.
.
Nominal types have slightly worse ergonomics since you need to have APIs for producing and modifying the type. For example even though nom_index
is a non_neg_integer()
, we can't say Index + 1
in nom.erl
. Instead we would need a function nom_index:next/1
which returns a nom_index:t()
.
Nominal typing is very powerful, however, and a really great addition to the Erlang type system, because the dialyzer can now distinguish between two types which are structurally equivalent bu