Was ist der Unterschied, wenn ich das schreibe?
data Book = Book Int Int
gegen
newtype Book = Book (Int, Int) -- "Book Int Int" is syntactically invalid
haskell
types
type-systems
newtype
ewggwegw
quelle
quelle
newtype Book = Book Int Int
nicht gültig ist. Sie können jedochnewtype Book = Book (Int, Int)
wie von Dons unten angegeben haben.Antworten:
Gute Frage!
Es gibt mehrere wesentliche Unterschiede.
Darstellung
newtype
garantiert, dass Ihre Daten zur Laufzeit genau dieselbe Darstellung haben wie der Typ, den Sie umbrechen.data
deklariert zur Laufzeit eine brandneue Datenstruktur.Der entscheidende Punkt hierbei ist also, dass das Konstrukt für das
newtype
beim Kompilieren garantiert gelöscht wird.Beispiele:
data Book = Book Int Int
newtype Book = Book (Int, Int)
Beachten Sie, dass es genau die gleiche Darstellung wie a hat
(Int,Int)
, da derBook
Konstruktor gelöscht wird.data Book = Book (Int, Int)
Hat einen zusätzlichen
Book
Konstruktor nicht in dernewtype
.data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int
Keine Hinweise! Die beiden
Int
Felder sind wortgroße Felder imBook
Konstruktor.Algebraische Datentypen
Aufgrund dieser Notwendigkeit, den Konstruktor zu löschen,
newtype
funktioniert a nur, wenn ein Datentyp mit einem einzelnen Konstruktor umbrochen wird . Es gibt keine Vorstellung von "algebraischen" neuen Typen. Das heißt, Sie können kein Newtype-Äquivalent von beispielsweise schreiben.da es mehr als einen Konstruktor hat. Du kannst auch nicht schreiben
Strenge
Die Tatsache, dass der Konstruktor gelöscht wird, führt zu einigen sehr subtilen Unterschieden in der Strenge zwischen
data
undnewtype
. Insbesondere wirddata
ein Typ eingeführt, der "angehoben" wird, was im Wesentlichen bedeutet, dass er eine zusätzliche Möglichkeit bietet, einen unteren Wert zu ermitteln. Da es zur Laufzeit mit keinen zusätzlichen Konstruktor gibtnewtype
, gilt diese Eigenschaft nicht.Mit diesem zusätzlichen Zeiger im
Book
to-(,)
Konstruktor können wir einen unteren Wert eingeben.Infolgedessen
newtype
unddata
haben leicht unterschiedliche Strengeigenschaften, wie im Haskell-Wiki-Artikel erläutert .Unboxing
Es ist nicht sinnvoll, die Komponenten von a zu entpacken
newtype
, da es keinen Konstruktor gibt. Während es völlig vernünftig ist zu schreiben:Ausgeben eines Laufzeitobjekts mit einem
T
Konstruktor und einerInt#
Komponente. Sie bekommen nur eine nackteInt
mitnewtype
.Referenzen :
quelle
newtype
nach dem Kompilieren gelöscht wird und die Laufzeit dieselbe Darstellung für alte und neue Typen verwendet. Wie können wir dann noch Instanzen für alte und neue Typen definieren? Wie kann die Laufzeit verstehen, welche Instanz verwendet werden soll?newtype
werden sie offensichtlich noch nicht gelöscht.