One helpful way to think about types is to consider its cardinality — that is, how many possible distinct values does it have?
For example in Elm, this custom
Direction type has exactly 4 distinct values
that can be constructed (you could say it has a cardinality of 4).
type Direction = North | South | East | West
Photo by Jordan Ladikos on Unsplash
Similarly, we can say the
Bool type has two distinct values (
False). The empty tuple
() type has single possible value - an empty
We’ve seen it’s possible to create types with cardinalities of 4, 2, and 1. You may wonder, is it possible to create a type that has zero possible values?
Elm has a type
Never that does just that. The type name
Never can still be
used in function signatures but it’s impossible to actually create a value of
This is done with a clever trick. The definition looks like this:
type Never = JustOneMore Never
This type is defined recursively. Because there is no base case, constructing
a value of type
Never is an infinite job.
aNeverValue : Never aNeverValue = JustOneMore (JustOneMore (JustOneMore ...) )
So it’s possible to create a type with zero values. Is this more than just a curiosity? Is it actually useful? Yes.
perform : (a -> msg) -> Task Never a -> Cmd msg
This signature says that
perform can only be called on tasks that cannot
fail. All other tasks have to use the
attempt function that will force you to
do some error handling. That’s a really useful distinction to be able to make!
-- The `a` is never used anywhere type Currency a = Currency Int
We would like to be able to create types like
Currency Dollar or
Euro. We could create our own
Euro types. Since we only care
about the type in the signature and not in the body, we can do some fanciness to
create types that can never be instantiated.
To accomplish this we can define these types as infinitely recursive, similar
Never type. Just like
Euro can never be
-- These two types are infinitely recursive. -- Similar to `Never`, they can never be instantiated. type Dollar = OneMoreDollar Dollar type Euro = OneMoreEuro Euro