W Haskell można określić typ danych algebraicznych bez konstruktora:Jaki jest cel algebraicznych typów danych bez konstruktora?
data Henk
Ale jaki jest cel takiego typu lub rodzaju (?), Który nie posiada konstruktora?
W Haskell można określić typ danych algebraicznych bez konstruktora:Jaki jest cel algebraicznych typów danych bez konstruktora?
data Henk
Ale jaki jest cel takiego typu lub rodzaju (?), Który nie posiada konstruktora?
Maszyny typu poziom często wymagają typów, ale nigdy nie konstruują wartości takich typów.
np fantomowe typy:
module Example (Unchecked, Checked, Stuff()) where
data Unchecked
data Checked
data Stuff c = S Int String Double
check :: Stuff Unchecked -> Maybe (Stuff Checked)
check (S i s d) = if i>43 && ...
then Just (S i s d)
else Nothing
readFile :: Filepath -> IO (Stuff Unchecked)
readFile f = ...
workWithChecked :: Stuff Checked -> Int -> String
workWithChecked stuff i = ...
workWithAny :: Stuff any -> Int -> Stuff any
workWithAny stuff i = ...
Dopóki konstruktor S
nie jest eksportowana przez moduł, użytkownik tej biblioteki nie można podrobić statusu z „zaznaczone” na typ danych Stuff
.
Powyżej, funkcja workWithChecked
nie musi dezynfekować wejścia za każdym razem, gdy jest wywoływana. Użytkownik musiał już to zrobić, ponieważ musi podać wartość w typie "sprawdzonym" - oznacza to, że użytkownik musiał wcześniej zadzwonić do funkcji check
. Jest to wydajna i solidna konstrukcja: nie powtarzamy tego samego sprawdzenia w kółko przy każdym połączeniu, a mimo to nie zezwalamy użytkownikowi na przesyłanie niezaznaczonych danych.
Uwaga, że wartości typów Checked
, Unchecked
są bez znaczenia - nigdy ich nie używamy.
Jak wspomniano w komentarzach, istnieje wiele innych zastosowań typów pustych niż fantomowych. Na przykład niektóre GADT dotyczą typów pustych. Na przykład.
Powyżej wykorzystujemy puste typy do zapisywania informacji o długości w typach.
Ponadto potrzebne są typy bez konstruktorów do osiągnięcia pewnych właściwości teoretyczne: jeśli spojrzymy za a
takie, że Either a T
jest izomorficzna T
chcemy a
być pusta. W teorii typów pusty typ jest powszechnie używany jako odpowiednik typu logicznie "fałszywej" propozycji.
To tylko część tego, dlaczego typy fantomów są użyteczne. Aby rozszerzyć twój przykład: możesz również mieć kilka funkcji, które działały poprawnie na zaznaczonych lub niezaznaczonych 'Rzeczy" i innych funkcjach, które działały tylko na sprawdzonej wersji. –
@JeremyList Całkowicie się zgadzam (w przeciwnym razie moglibyśmy po prostu użyć dwóch różnych typów zamiast indeksu fantomowego). Dodałem jeszcze jedną funkcję, aby trochę poprawić, nawet pełna moc typów fantomowych nie jest tutaj pokazana. – chi
są to nazywane typy fantomowe; są użyteczne przy parametryzacji innych typów, tj. przekazywaniu jako parametru typu do konstruktorów typów, żaden z konstruktorów wartości nie oczekuje parametru wartości tego typu fantomowego. –
Nieważne typy fantomów (więc nie jest to duplikat, Erik), istnieje wiele rozsądnych motywacji dla przynajmniej jednego * pustego * typu: http://stackoverflow.com/q/14131856/828361 – pigworker