où est la différence quand j’écris
Réponse
Trop de publicités?Excellente question!
Il y a plusieurs différences clés.
La représentation
- Un
newtype
garantit que vos données ont exactement la même représentation au moment de l'exécution, comme le type que vous envelopper. - Alors qu'
data
déclare une marque nouvelle structure de données lors de l'exécution.
Donc, le point clé ici est que la construction de l' newtype
est garanti pour être effacé au moment de la compilation.
Exemples:
data Book = Book Int Int
newtype Book = Book (Int, Int)
Notez comment il a exactement la même représentation en tant que (Int,Int)
, depuis l' Book
constructeur est effacé.
data Book = Book (Int, Int)
A un autre Book
constructeur n'est pas présent dans l' newtype
.
data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int
Pas de pointeurs! Les deux Int
champs sont "unboxed" mot de la taille des champs dans l' Book
constructeur.
Types de données algébriques
En raison de ce besoin d'effacer le constructeur, un newtype
ne fonctionne que lorsque l'enveloppant d'un type de données avec un seul constructeur. Il n'y a pas de notion de "algébrique" newtypes. Qui est, vous ne pouvez pas écrire un newtype équivalent, disons,de la
data Maybe a = Nothing
| Just a
car il a plus d'un constructeur. De même, vous pouvez écrire
newtype Book = Book Int Int
Rigueur
Le fait que le constructeur est effacé mène à des différences subtiles dans la rigueur entre data
et newtype
. En particulier, data
introduit un type qui est "élevé", ce qui signifie, en substance, qu'il y a une autre manière de l'évaluer à une valeur inférieure. Depuis il n'y a aucun constructeur au moment de l'exécution avec newtype
, cette propriété ne tient pas.
Extra pointeur dans l' Book
de (,)
constructeur nous permet de mettre une valeur inférieure.
En conséquence, newtype
et data
sont légèrement différentes de rigueur propriétés, comme expliqué dans le Haskell article de wiki.
Unboxing
Il ne fait pas de sens pour unbox les composants d'un newtype
, car il n'y a pas de constructeur. Alors qu'il est parfaitement raisonnable d'écrire:
data T = T {-# UNPACK #-}!Int
ce qui donne un objet d'exécution avec un T
constructeur, et un Int#
de la composante. Vous venez de recevoir un nu - Int
avec newtype
.
Références:
- "Newtype" sur le Haskell wiki
- Norman Ramsey, en réponse à propos de la rigueur propriétés