La risposta di Karl è buona. Ecco un ulteriore uso che non penso che sia stato menzionato da nessun altro. Il tipo di
if E then A else B
dovrebbe essere un tipo che include tutti i valori nel tipo di A
e tutti i valori nel tipo di B
. Se il tipo di B
è Nothing
, il tipo if
dell'espressione può essere il tipo di A
. Dichiarerò spesso una routine
def unreachable( s:String ) : Nothing = throw new AssertionError("Unreachable "+s)
per dire che il codice non dovrebbe essere raggiunto. Dal momento che il suo tipo è Nothing
, unreachable(s)
ora può essere utilizzato in qualsiasi if
o (più spesso) switch
senza influire sul tipo di risultato. Per esempio
val colour : Colour := switch state of
BLACK_TO_MOVE: BLACK
WHITE_TO_MOVE: WHITE
default: unreachable("Bad state")
Scala ha un tale tipo di niente.
Un altro caso d'uso per Nothing
(come menzionato nella risposta di Karl) è Elenco [Niente] è il tipo di elenchi ciascuno dei cui membri ha il tipo Nulla. Quindi può essere il tipo di elenco vuoto.
La proprietà chiave Nothing
che fa funzionare questi casi d'uso non è che non abbia valori - sebbene in Scala, ad esempio, non abbia valori - è che è un sottotipo di ogni altro tipo.
Supponiamo di avere una lingua in cui ogni tipo contiene lo stesso valore: chiamiamolo ()
. In tale linguaggio il tipo di unità, che ha ()
come unico valore, potrebbe essere un sottotipo di ogni tipo. Ciò non lo rende un tipo di fondo, nel senso che significava OP; l'OP era chiaro che un tipo di fondo non contiene valori. Tuttavia, poiché è un tipo che è un sottotipo di ogni tipo, può svolgere lo stesso ruolo di un tipo di fondo.
Haskell fa le cose in modo leggermente diverso. In Haskell, un'espressione che non produce mai un valore può avere lo schema dei tipi forall a.a
. Un'istanza di questo schema di tipi si unificherà con qualsiasi altro tipo, quindi agisce efficacemente come tipo di fondo, anche se (standard) Haskell non ha alcuna nozione di sottotipo. Ad esempio, la error
funzione del preludio standard ha uno schema di tipi forall a. [Char] -> a
. Quindi puoi scrivere
if E then A else error ""
e il tipo di espressione sarà lo stesso del tipo di A
, per qualsiasi espressione A
.
L'elenco vuoto in Haskell ha lo schema dei tipi forall a. [a]
. If A
è un'espressione il cui tipo è un tipo di elenco, quindi
if E then A else []
è un'espressione con lo stesso tipo di A
.
void
dato ...