Odpowiedź Karla jest dobra. Oto dodatkowe zastosowanie, które, jak sądzę, nikt inny nie wspomniał. Typ
if E then A else B
powinien być typem, który zawiera wszystkie wartości w typie A
i wszystkie wartości w typie B
. Jeśli typem B
jest Nothing
, typem if
wyrażenia może być typ A
. Często ogłaszam rutynę
def unreachable( s:String ) : Nothing = throw new AssertionError("Unreachable "+s)
stwierdzenie, że kod nie zostanie osiągnięty. Ponieważ jest to typ Nothing
, unreachable(s)
można go teraz używać w dowolnym if
lub (częściej) switch
bez wpływu na rodzaj wyniku. Na przykład
val colour : Colour := switch state of
BLACK_TO_MOVE: BLACK
WHITE_TO_MOVE: WHITE
default: unreachable("Bad state")
Scala ma taki typ Nic.
Innym przypadkiem użycia Nothing
(jak wspomniano w odpowiedzi Karla) jest Lista [Nic] to typ list, których każdy członek ma typ Nic. Może to być typ pustej listy.
Kluczową właściwością, Nothing
która sprawia, że te przypadki użycia działają, jest to, że nie ma żadnych wartości - chociaż na przykład w Scali nie ma żadnych wartości - jest to, że jest to podtyp każdego innego typu.
Załóżmy, że masz język, w którym każdy typ zawiera tę samą wartość - nazwijmy go ()
. W takim języku typ jednostki, który ma ()
jako jedyną wartość, może być podtypem każdego typu. Nie oznacza to, że jest to typ dna w tym sensie, że miał na myśli PO; PO było jasne, że typ dna nie zawiera żadnych wartości. Ponieważ jednak jest to typ, który jest podtypem każdego typu, może odgrywać taką samą rolę jak typ dolny.
Haskell robi rzeczy nieco inaczej. W Haskell wyrażenie, które nigdy nie tworzy wartości, może mieć schemat typów forall a.a
. Instancja tego typu schematu połączy się z dowolnym innym typem, więc skutecznie działa jako typ dolny, mimo że (standardowy) Haskell nie ma pojęcia podtypu. Na przykład error
funkcja ze standardowego preludium ma schemat typów forall a. [Char] -> a
. Więc możesz pisać
if E then A else error ""
a typ wyrażenia będzie taki sam jak typ A
dowolnego wyrażenia A
.
Pusta lista w Haskell ma schemat typów forall a. [a]
. Jeśli A
jest wyrażeniem, którego typ jest typem listy, to
if E then A else []
jest wyrażeniem tego samego typu co A
.
void
danych ...