2013-02-11 9 views
6

Worin besteht der Unterschied in verschiedenen Phasen der Read-Compile-Run-Pipeline zwischen einer type Deklaration und einer newtype Deklaration?Kompilierzeit und Laufzeitdifferenz zwischen Typ und Newtype

Meine Vermutung war, dass sie den gleichen Maschinenbefehle zusammengestellt nach unten, und dass der einzige Unterschied war, wenn das Programm typechecked, wo zum Beispiel

type Name = String 
newtype Name_ = N String 

Sie einen Name überall benötigt ein String wird verwenden können, aber der Typchecker wird Sie aufrufen, wenn Sie eine Name_ verwenden, wo eine String erwartet wird, obwohl sie die gleichen Informationen codieren.

Ich frage die Frage, denn wenn dies der Fall ist, ich keinen Grund, warum die folgenden Erklärungen nicht gültig sein sollte:

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

übernimmt jedoch die Typprüfer die zweite einer aber lehnt den ersten ab. Warum das?

+10

Es ist kein Kompilierungsproblem, es ist ein Typprüfungsproblem. Haskell verwendet "iso-rekursive Typen" und nicht "gleich rekursive Typen". Wenn Sie also einen rekursiven Typ haben wollen, müssen Sie irgendwo einen 'data' oder einen' newtype' haben. Es gibt verschiedene Kompromisse zu jeder Wahl. Unter Typen und Programmiersprachen von Pierce finden Sie weitere Informationen zu diesen Systemen und den entsprechenden Optionen. – luqui

+2

Danke, ich glaube, ich brauchte nur die Namen "iso-recursive" und "equirecursive", um zu wissen, wofür Google ist! Wenn du das in eine Antwort umwandeln willst, akzeptiere ich es. –

Antwort

4

Luquis Kommentar sollte eine Antwort sein. Typensynonyme in Haskell sind in erster Näherung nichts anderes als Makros. Das heißt, sie werden vom Typchecker in vollständig ausgewertete Typen erweitert. Die Typüberprüfung kann keine unendlichen Typen verarbeiten, daher hat Haskell keine gleich rekursiven Typen.

newtypes stellen Sie iso-rekursive Typen bereit, die in GHC im Wesentlichen zu gleichgerichteten Typen in der Kernsprache kompilieren. Haskell ist kein GHC-Kern, Sie haben also keinen Zugriff auf solche Typen. Gleich rekursive Typen sind nur etwas schwieriger mit Typ-Checkern und Menschen zu arbeiten, während iso-rekursive Typen äquivalent sind.

+0

Danke Philip. Habe ich richtig verstanden, dass GHC Core gleich rekursive Typen hat? In welchem ​​Stadium verschwinden die Informationen im Tag "newtype"? –

+0

Ich vermeide Kern wie die Pest, also nimm alles, was ich sage, mit einem Körnchen Salz: GHC-Kern hat iso-rekursive Typen. Und neue Typen existieren nicht im Kern. Ich glaube, dass dies in Zukunft durch die Verwendung von Typgleichheitsbedingungen ersetzt werden kann: also "List_ a = (Entweder() (a, r)) ~ r => r" mit Beweisen für diese Gleichheiten, die bei jedem Anwendungsfall eingefügt werden (Die Maschinerie dafür existiert bereits). –

+0

@PhilipJF: [Es ist ein wenig komplizierter.] (Http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/FC#Newtypesarecoercedtypes) Im Moment kompilieren newtypes in einen Datentyp und einen Typ Gleichheitsaxiom: 'newtype T = MkT Int' erzeugt das Axiom' axT: T ~ Int'. Leider ist das nicht stichhaltig: wenn wir 'type family F a haben; Typinstanz F Int = Bool; Geben Sie die Instanz F T = Char ', dann 'Bool ~ F Int',' F Int ~ F T' und 'F T ~ Char 'ein. Also 'Bool ~ Char', und wir sind in Schwierigkeiten. [Dies kann tatsächlich mit 'GeneralizedNewtypeDeriving' gekitzelt werden.] (Http://hackage.haskell.org/trac/ghc/ticket/1496) –