La respuesta de Karl es buena. Aquí hay un uso adicional que no creo que nadie más haya mencionado. El tipo de
if E then A else B
debe ser un tipo que incluya todos los valores en el tipo de A
y todos los valores en el tipo de B
. Si el tipo de B
es Nothing
, entonces el tipo de expresión if
puede ser el tipo de A
. A menudo declararé una rutina
def unreachable( s:String ) : Nothing = throw new AssertionError("Unreachable "+s)
para decir que no se espera que se alcance el código. Como su tipo es Nothing
, unreachable(s)
ahora se puede usar en cualquier if
o (más a menudo) switch
sin afectar el tipo de resultado. Por ejemplo
val colour : Colour := switch state of
BLACK_TO_MOVE: BLACK
WHITE_TO_MOVE: WHITE
default: unreachable("Bad state")
Scala tiene ese tipo de Nada.
Otro caso de uso para Nothing
(como se menciona en la respuesta de Karl) es la Lista [Nothing] es el tipo de listas de cada miembro cuyos miembros tienen el tipo Nothing. Por lo tanto, puede ser el tipo de la lista vacía.
La propiedad clave de Nothing
que hace que estos casos de uso funcionen es no que no tiene valores (aunque en Scala, por ejemplo; no tiene valores), es que es un subtipo de cualquier otro tipo.
Supongamos que tiene un idioma donde cada tipo contiene el mismo valor, llamémoslo ()
. En tal idioma, el tipo de unidad, que tiene ()
como su único valor, podría ser un subtipo de cada tipo. Eso no lo convierte en un tipo de fondo en el sentido que significaba el OP; El OP estaba claro que un tipo de fondo no contiene valores. Sin embargo, como es un tipo que es un subtipo de cada tipo, puede desempeñar la misma función que el tipo de fondo.
Haskell hace las cosas de manera un poco diferente. En Haskell, una expresión que nunca produce un valor puede tener el tipo forall a.a
. Una instancia de este esquema de tipo se unirá con cualquier otro tipo, por lo que actúa efectivamente como un tipo de fondo, aunque Haskell (estándar) no tiene noción de subtipo. Por ejemplo, la función error
del preludio estándar tiene un esquema de tipo forall a. [Char] -> a
. Así que puedes escribir
if E then A else error ""
y el tipo de expresión será el mismo que el tipo de A
, para cualquier expresión A
.
La lista vacía en Haskell tiene el esquema de tipo forall a. [a]
. Si A
es una expresión cuyo tipo es un tipo de lista, entonces
if E then A else []
es una expresión con el mismo tipo que A
. El tipo de []
es el mismo que el tipo [error ""]
, que muestra que la lista vacía no es el único valor de su tipo.