Dlaczego nie są równoważne?
show $ if someCondition then someInt else some double
i
if someCondition then show someInt else show someDouble
Rozumiem, że jeśli wyodrębnisz if ... else
część w pierwszym przykładzie do wyrażenia samodzielnie, nie będziesz mógł reprezentować jego typu za pomocą anonimowego typu sumy, takiego Int | Double
jak coś, co można łatwo zrobić w TypeScript (wspominając o TypeScript, ponieważ jest to langauge, którego często używałem i który obsługuje typy Sum), i musiałbym skorzystać z Either
danych, a następnie na podstawie tego zadzwonić show
.
Podany przeze mnie przykład jest trywialny, ale dla mnie bardziej sensowne jest myślenie „OK, pokażemy coś i że coś zależy od someCondition
”, a nie „OK, jeśli jakiś warunek jest prawdziwy, to pokaż niektóre, w przeciwnym razie pokaż jakieś double”, a także pozwala dla mniejszego duplikowania kodu (tutaj pokaz powtarza się dwa razy, ale może to być również długa aplikacja funkcji i zamiast if ... else
niej można rozważyć> 2 gałęzie)
Moim zdaniem kompilator powinien łatwo sprawdzić, czy każdy z typów tworzących typ sumy (tutaj Int | Double
) może być użyty jako parametr do show
działania i decyduje, czy typy są poprawne, czy nie. Jeszcze lepsze jest to, że show
funkcja zawsze zwraca string
bez względu na typy parametrów, więc kompilator nie musi nosić ze sobą wszystkich możliwych „gałęzi” (czyli wszystkich możliwych typów).
Czy z wyboru taka funkcja nie istnieje? Czy może wdrażanie jest trudniejsze niż myślę?
źródło
if ... then ... else ...
musi mieć ten sam typ w częścithen
ielse
. W niektórych językach programowania można go postrzegać jako operator trójskładnikowy.making all conversions explicit
. Na moje pytanie, nie chcę Haskell rzutowaćInt
DoDouble
lub vice versa. Właśnie użyłem tych dwóch typów jako przykładu. Można zastąpić każdyInt
za
aDouble
zb
moim pytaniem, gdzie oba typy wywodząShow
. Rozumiem, że nie ma goanonymous sum types
w Haskell, ale chciałbym wiedzieć, dlaczego tak jest i co powstrzymuje nas od zaprojektowania języka, aby go mieć.x :: Int | Bool
i musimy skompilowaćshow x
, nie ma łatwego sposobu, aby dowiedzieć się, którego wskaźnika użyć do wywołaniashow
, w RTS opartym na usuwaniu typów. Prawdopodobnie musielibyśmy zachować pewne informacje na poziomie typu w czasie wykonywania.(String, Int)
nie jest anonimowy. Jest to zwykły typ produktu ze śmieszną składnią.(String | Int)
byłoby zupełnie inaczej. Zacznij od pytania, czy(Int|Int)
powinno być identyczneInt
i dlaczego.Odpowiedzi:
Wszystkie części wyrażenia muszą być dobrze napisane. Taki typ
if someCondition then someInt else someDouble
musiałby być podobnyexists a. Show a => a
, ale Haskell nie obsługuje tego rodzaju egzystencjalnej kwantyfikacji.Aktualizacja: jak chi wskazuje w komentarzu , byłoby to również możliwe, gdyby Haskell obsługiwał typy złączy / skrzyżowań (które nie są takie same jak typy sum / typów), ale niestety nie.
źródło
Int ∪ Double
, wiedziałbyś, że masz jeden z dwóch, ale nie byłbyś w stanie dopasować wzoru, aby zobaczyć, który z nich, więc możesz robić tylko rzeczy, które byłyby uzasadnione dla obu możliwości.typeof
operator, który może zrekompensować brak tagowania i zobaczyć, który typ jest używany. Haskell jest w pełni wymazany, więc jeśli obsługiwałby tę funkcję, to nie byłoby tego równoważne.Istnieją typy produktów o lekkiej składni, napisane
(,)
, w języku Haskell. Można by pomyśleć, że typ sumy z lekką składnią, coś w stylu(Int | String)
, byłby świetnym pomysłem. Rzeczywistość jest bardziej skomplikowana. Zobaczmy, dlaczego (zabieram trochę swobódNum
, nie są one ważne).Jeśli to powinno zwrócić wartość typu typu
(Int | String)
, to co powinien zwrócić następujący?(Int | Int)
oczywiście, ale jeśli to różni się od zwykłegoInt
mamy poważne kłopoty.(Int | Int)
Powinien więc być identyczny jak zwykłyInt
.Od razu widać, że jest to nie tylko lekka składnia dla typów sum, ale całkowicie nowa funkcja języka. Inny rodzaj systemu typów, jeśli chcesz. Powinniśmy mieć?
Spójrzmy na tę funkcję.
Teraz jaki typ
mysteryType
ma? Oczywiściedobrze? Co teraz, jeśli
a
ib
są tego samego typu?Powinno to być jasne,
Int
jak wcześniej uzgodniliśmy. TerazmysteryType
czasami zwraca anonimowy typ sumy, a czasem nie, w zależności od przekazywanych argumentów. Jak pasowałbyś do takiego wyrażenia? Co na ziemi możesz z tym zrobić? Z wyjątkiem trywialnych rzeczy, takich jak „pokaż” (lub dowolnych metod innych klas typów, których byłby to przypadek), nie wiele. Chyba że dodasz do języka informacje o typie wykonawczym, to znaczy, żetypeof
jest ono dostępne - i to sprawi, że Haskell będzie zupełnie innym językiem.Więc tak. Dlaczego Haskell nie jest TypeScript? Ponieważ nie potrzebujemy innego TypeScript. Jeśli chcesz TypeScript, wiesz, gdzie go znaleźć.
źródło