La réponse de Karl est bonne. Voici une utilisation supplémentaire que personne, à mon avis, n’a mentionnée. Le type de
if E then A else B
devrait être un type qui inclut toutes les valeurs du type A
et toutes les valeurs du type B
. Si le type B
est Nothing
, alors le type de l' if
expression peut être le type de A
. Je déclare souvent une routine
def unreachable( s:String ) : Nothing = throw new AssertionError("Unreachable "+s)
dire que le code ne devrait pas être atteint. Comme son type est Nothing
, unreachable(s)
peut maintenant être utilisé dans n’importe quel if
ou (plus souvent) switch
sans affecter le type de résultat. Par exemple
val colour : Colour := switch state of
BLACK_TO_MOVE: BLACK
WHITE_TO_MOVE: WHITE
default: unreachable("Bad state")
Scala a un tel type rien.
Un autre cas d'utilisation Nothing
(comme mentionné dans la réponse de Karl) est List [Nothing] est le type de listes dont chacun des membres a le type Nothing. Cela peut donc être le type de la liste vide.
La propriété de clé Nothing
qui fait fonctionner ces cas d'utilisation n'est pas qu'elle n'a pas de valeur - bien que dans Scala, par exemple, elle n'a pas de valeur - c'est qu'il s'agit d'un sous-type de tous les autres types.
Supposons que vous ayez une langue où chaque type contient la même valeur - appelons-le ()
. Dans un tel langage, le type d'unité, qui a ()
pour seule valeur, pourrait être un sous-type de chaque type. Cela n'en fait pas un type de fond au sens où l'entend l'OP; le PO était clair qu'un type de fond ne contient aucune valeur. Cependant, comme il s'agit d'un type qui est un sous-type de chaque type, il peut jouer à peu près le même rôle qu'un type inférieur.
Haskell fait les choses un peu différemment. En Haskell, une expression qui ne produit jamais de valeur peut avoir le schéma de type forall a.a
. Une instance de ce schéma de type s'unira avec tout autre type, de sorte qu'elle agit effectivement comme un type de fond, même si Haskell (standard) ne possède aucune notion de sous-typage. Par exemple, la error
fonction du prélude standard a un schéma de types forall a. [Char] -> a
. Donc tu peux écrire
if E then A else error ""
et le type de l'expression sera le même que le type de A
, pour toute expression A
.
La liste vide dans Haskell a le schéma de type forall a. [a]
. Si A
est une expression dont le type est un type de liste, alors
if E then A else []
est une expression du même type que A
.
void
donnée en C ...