|
| 1 | +# Tuples containing `Never` |
| 2 | + |
| 3 | +A heterogeneous `tuple[…]` type that contains `Never` as a type argument simplifies to `Never`. One |
| 4 | +way to think about this is the following: in order to construct a tuple, you need to have an object |
| 5 | +of every element type. But since there is no object of type `Never`, you cannot construct the tuple. |
| 6 | +Such a tuple type is therefore uninhabited and equivalent to `Never`. |
| 7 | + |
| 8 | +In the language of algebraic data types, a tuple type is a product type and `Never` acts like the |
| 9 | +zero element in multiplication, similar to how a Cartesian product with the empty set is the empty |
| 10 | +set. |
| 11 | + |
| 12 | +```py |
| 13 | +from knot_extensions import static_assert, is_equivalent_to |
| 14 | +from typing_extensions import Never, NoReturn |
| 15 | + |
| 16 | +static_assert(is_equivalent_to(Never, tuple[Never])) |
| 17 | +static_assert(is_equivalent_to(Never, tuple[Never, int])) |
| 18 | +static_assert(is_equivalent_to(Never, tuple[int, Never])) |
| 19 | +static_assert(is_equivalent_to(Never, tuple[int, Never, str])) |
| 20 | +static_assert(is_equivalent_to(Never, tuple[int, tuple[str, Never]])) |
| 21 | +static_assert(is_equivalent_to(Never, tuple[tuple[str, Never], int])) |
| 22 | + |
| 23 | +# The empty tuple is *not* equivalent to Never! |
| 24 | +static_assert(not is_equivalent_to(Never, tuple[()])) |
| 25 | + |
| 26 | +# NoReturn is just a different spelling of Never, so the same is true for NoReturn |
| 27 | +static_assert(is_equivalent_to(NoReturn, tuple[NoReturn])) |
| 28 | +static_assert(is_equivalent_to(NoReturn, tuple[NoReturn, int])) |
| 29 | +static_assert(is_equivalent_to(NoReturn, tuple[int, NoReturn])) |
| 30 | +static_assert(is_equivalent_to(NoReturn, tuple[int, NoReturn, str])) |
| 31 | +static_assert(is_equivalent_to(NoReturn, tuple[int, tuple[str, NoReturn]])) |
| 32 | +static_assert(is_equivalent_to(NoReturn, tuple[tuple[str, NoReturn], int])) |
| 33 | +``` |
0 commit comments