I think that `enum`

declarations can be useful to get the number of elements in the set right.

Consider

```
enum TwoValues { First, Second }
```

The type `TwoValues`

has two values, those are `TwoValues::First`

and `TwoValues::Second`

. Describing the set of all value of type `TwoValues`

, that’s a 2-element set,

{`TwoValues::First`

, `TwoValues::Second`

}

Conveniently, the `enum`

declaration itself already almost looks like this set: ` { First, Second }`

.

Next example, going lower:

```
enum OneValue { First }
```

well, that’s a type with a single value. Every instance of `OnceValue`

will be `OneValue::First`

, while the value of type `TwoValues`

can be represented with 1 bit of data, a value of type `OneValue`

needs 0 bits of data. Thus it’s a zero-sized type, still the set of values isn’t a 0-element set, but a 1-element set, namely the set

{`OneValue::First`

}

Going lower:

```
enum ZeroValues { }
```

now that’s an enum without any values at all. You cannot construct a value of type `ZeroValues`

. If a function promises “if I return, then I return a value of type `ZeroValues`

”, then you *know* that that function will never return. Because values of type `ZeroValues`

don’t exist. The set of all value of type `ZeroValues`

exists: It’s the set

{ }

or sometimes written

∅

so the “empty set”. The fact that no values of `ZeroValues`

exists then corresponds to the fact that no elements of the empty set exist. The set itself exists, but elements of it don’t.

Comparing these enums with more canonical types from the Rust standard library, we’d have

the type `TwoValues`

is like the type `bool`

,

the value `TwoValues::First`

corresponds to the value `false`

,

the value `TwoValues::Second`

corresponds to the value `true`

,

the type `OneValue`

is like the type `()`

the value `OneValue::First`

corresponds to the value the value `()`

,

the type `ZeroValues`

is like the type `!`