# Types without values

Joël Quenneville

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 (`True` and `False`). The empty tuple `()` type has single possible value - an empty tuple.

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?

## Never

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 type `Never`.

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 ...) )
``````

## Uses

So it’s possible to create a type with zero values. Is this more than just a curiosity? Is it actually useful? Yes.

The `Never` type is really valuable when trying to constrain the signatures of other types. For example `Task.perform` from `elm/core`:

``````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!

## Use with phantom types

Phantom types are types that declare a type parameter but never use it. For example:

``````-- The `a` is never used anywhere

type Currency a
= Currency Int
``````

We would like to be able to create types like `Currency Dollar` or ```Currency Euro```. We could create our own `Dollar` or `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 to Elm’s `Never` type. Just like `Never`, `Dollar` and `Euro` can never be instantiated.

``````-- These two types are infinitely recursive.
-- Similar to `Never`, they can never be instantiated.

type Dollar
= OneMoreDollar Dollar

type Euro
= OneMoreEuro Euro
``````