Ottima domanda!
Esistono diverse differenze chiave.
Rappresentazione
- A
newtype
garantisce che i tuoi dati avranno esattamente la stessa rappresentazione in fase di esecuzione, come il tipo che avvolgi.
- Mentre
data
dichiara una nuova struttura di dati in fase di esecuzione.
Quindi il punto chiave qui è che il costrutto per il newtype
è garantito per essere cancellato al momento della compilazione.
Esempi:
newtype Book = Book (Int, Int)
Nota come ha esattamente la stessa rappresentazione di a (Int,Int)
, poiché il Book
costruttore viene cancellato.
data Book = Book (Int, Int)
Ha un Book
costruttore aggiuntivo non presente in newtype
.
data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int
Nessun puntatore! I due Int
campi sono campi di dimensioni di parola senza riquadro nel Book
costruttore.
Tipi di dati algebrici
A causa di questa necessità di cancellare il costruttore, newtype
funziona solo quando si avvolge un tipo di dati con un solo costruttore . Non c'è idea di newtypes "algebrici". Cioè, non puoi scrivere un equivalente newtype di, diciamo,
data Maybe a = Nothing
| Just a
poiché ha più di un costruttore. Né puoi scrivere
newtype Book = Book Int Int
Rigore
Il fatto che il costruttore venga cancellato porta ad alcune sottili differenze di rigore tra data
e newtype
. In particolare, data
introduce un tipo che viene "sollevato", il che significa essenzialmente che ha un modo aggiuntivo di valutare un valore inferiore. Poiché non è disponibile alcun costruttore aggiuntivo in fase di runtime newtype
, questa proprietà non è valida.
Quel puntatore in più Book
nel (,)
costruttore to ci consente di inserire un valore inferiore.
Di conseguenza, newtype
e data
hanno proprietà di rigidezza leggermente diverse, come spiegato nell'articolo wiki di Haskell .
Spacchettamento
Non ha senso decomprimere i componenti di a newtype
, poiché non esiste alcun costruttore. Mentre è perfettamente ragionevole scrivere:
data T = T {-# UNPACK #-}!Int
producendo un oggetto runtime con un T
costruttore e un Int#
componente. Basta avere una nuda Int
con newtype
.
Riferimenti :