A resposta de Karl é boa. Aqui está um uso adicional que acho que ninguém mais mencionou. O tipo de
if E then A else B
deve ser um tipo que inclua todos os valores no tipo de A
e todos os valores no tipo de B
. Se o tipo de B
for Nothing
, o tipo da if
expressão pode ser o tipo de A
. Eu frequentemente declaro uma rotina
def unreachable( s:String ) : Nothing = throw new AssertionError("Unreachable "+s)
dizer que não se espera que o código seja alcançado. Como seu tipo é Nothing
, unreachable(s)
agora pode ser usado em qualquer um if
(ou mais frequentemente) switch
sem afetar o tipo de resultado. Por exemplo
val colour : Colour := switch state of
BLACK_TO_MOVE: BLACK
WHITE_TO_MOVE: WHITE
default: unreachable("Bad state")
Scala tem esse tipo de Nada.
Outro caso de uso para Nothing
(como mencionado na resposta de Karl) é List [Nothing] é o tipo de lista em que cada membro tem o tipo Nothing. Assim, pode ser o tipo da lista vazia.
A propriedade-chave Nothing
que faz com que esses casos de uso funcionem não é que não tenha valores - embora no Scala, por exemplo, não tenha valores - é que é um subtipo de qualquer outro tipo.
Suponha que você tenha um idioma em que cada tipo contenha o mesmo valor - vamos chamá-lo ()
. Nesse idioma, o tipo de unidade, que tem ()
como único valor, pode ser um subtipo de todo tipo. Isso não o torna um tipo de base no sentido que o OP significava; o OP ficou claro que um tipo inferior não contém valores. No entanto, como é um tipo que é um subtipo de todo tipo, pode desempenhar o mesmo papel que um tipo inferior.
Haskell faz as coisas de maneira um pouco diferente. Em Haskell, uma expressão que nunca produz um valor pode ter o esquema de tipos forall a.a
. Uma instância desse esquema de tipo será unificada com qualquer outro tipo, portanto, atua efetivamente como um tipo inferior, mesmo que Haskell (padrão) não tenha noção de subtipagem. Por exemplo, a error
função do prelúdio padrão possui esquema de tipos forall a. [Char] -> a
. Então você pode escrever
if E then A else error ""
e o tipo da expressão será o mesmo que o tipo de A
, para qualquer expressão A
.
A lista vazia em Haskell possui o esquema de tipos forall a. [a]
. Se A
é uma expressão cujo tipo é um tipo de lista, então
if E then A else []
é uma expressão do mesmo tipo que A
.
void
dados ...