2013-02-11 20 views
6

Jaka jest różnica, na różnych etapach procesu odczytu-kompilacji, między deklaracją type a deklaracją newtype?Czas kompilacji i różnica czasu między typem a nowym typem:

Moim założeniem było to, że skompilowany w dół do tych samych instrukcji maszynowych, i że jedyną różnicą było to, gdy program jest typechecked, gdzie na przykład

type Name = String 
newtype Name_ = N String 

Można użyć Name wszędzie, gdzie String jest wymagane, ale typechecker wywoła cię, jeśli użyjesz Name_, gdzie oczekuje się String, mimo że kodują te same informacje.

pytam pytanie, ponieważ jeśli jest to przypadek, nie widzę żadnego powodu, dlaczego następujące deklaracje nie powinny być ważne:

type List a = Either() (a, List a) 
newtype List_ a = L (Either() (a, List_ a)) 

Jednak kontroler typu akceptuje sekundę jeden, ale odrzuca pierwszy. Dlaczego?

+10

Nie jest to problem kompilacji, jest to problem sprawdzający typ. Haskell używa "typów rekursywnych izo-rekurencyjnych" zamiast "typów equi-rekursywnych", więc jeśli chcesz, aby Twój typ był rekursywny, musisz mieć gdzieś "dane" lub "typ nowego". Z każdym wyborem wiąże się wiele różnych kompromisów. Zobacz "Typy i języki programowania" autorstwa Pierce'a, aby dowiedzieć się więcej o tych systemach i dostępnych opcjach. – luqui

+2

Dzięki, myślę, że po prostu potrzebowałem nazw "iso-recursive" i "equi-recursive", aby wiedzieć, co dla Google! Jeśli chcesz przekonwertować to na odpowiedź, zaakceptuję to. –

Odpowiedz

4

Komentarz Luqui powinien być odpowiedzią. Typ synonimów w Haskell są do pierwszego przybliżenia nic więcej niż makra. Oznacza to, że są one rozszerzane przez kontroler typu na w pełni oszacowane typy. Sprawdzanie typu nie może obsłużyć nieskończonych typów, więc Haskell nie ma typów rekursywnych.

newtypes zapewniają typy izo-rekursywne, które w GHC zasadniczo kompilują się do typów equi-rekursywnych w języku podstawowym. Haskell nie jest rdzeniem GHC, więc nie masz dostępu do takich typów. Typy wyrównujące rekurencję są nieco trudniejsze w pracy zarówno z kontrolerami typów jak i ludźmi, podczas gdy typy izo-rekursywne mają taką samą moc.

+0

Dzięki Philip. Czy mam rację, jeśli chodzi o zrozumienie, że GHC Core ma typy rekurencyjne? Na jakim etapie znika informacja z tagu "newtype"? –

+0

Unikałem rdzenia jak zarazy, więc weź wszystko, co powiem z przymrużeniem oka: rdzeń GHC ma typy rekursywne izo-rekurencyjne. A nowe typy nie istnieją w rdzeniu. Moim przekonaniem jest, że może to zostać zastąpione przez użycie ograniczeń równości typu w przyszłości: tak więc 'List_ a = (Either() (a, r)) ~ r => r' z dowodami tych równości wstawianych w każdym przypadku użycia (maszyny do tego już istnieją). –

+0

@PhilipJF: [To trochę bardziej skomplikowane.] (Http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/FC#Newtypesarecoercedtypes) W tej chwili nowe typy kompilują się w typ danych plus typ aksjomat równości: 'newtype T = MkT Int' tworzy aksjomat' axT: T ~ Int'. Niestety, jest to niesłuszne: jeśli mamy 'typ rodziny F a; wpisz instancję F Int = Bool; wpisz instancję F T = Char', następnie 'Bool ~ F Int',' F Int ~ F T' i 'F T ~ Char'. Tak więc 'Bool ~ Char' i mamy kłopoty. [To może rzeczywiście być łaskotane przez "GeneralizedNewtypeDeriving".] (Http://hackage.haskell.org/trac/ghc/ticket/1496) –

Powiązane problemy