Świetne pytanie!
Istnieje kilka kluczowych różnic.
Reprezentacja
- A
newtypegwarantuje, że dane będą miały dokładnie taką samą reprezentację w czasie wykonywania, jak rodzaj zawinąć.
- Podczas
datadeklaruje zupełnie nową strukturę danych w czasie wykonywania.
Kluczową kwestią jest tutaj to, że konstrukcja dla newtype gwarantowana jest wymazana w czasie kompilacji.
Przykłady:

newtype Book = Book (Int, Int)

Zauważ, że ma dokładnie taką samą reprezentację jak a (Int,Int), ponieważ Bookkonstruktor jest kasowany.
data Book = Book (Int, Int)

Ma dodatkowy Bookkonstruktor nieobecny w newtype.
data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int

Brak wskazówek! Te dwa Intpola są w konstruktorze rozpakowanymi polami wielkości słowa Book.
Algebraiczne typy danych
Z powodu tej potrzeby skasowania konstruktora: newtype działa tylko podczas owijania typu danych jednym konstruktorem . Nie ma pojęcia o „typach algebraicznych”. Oznacza to, że nie można napisać nowego odpowiednika, powiedzmy,
data Maybe a = Nothing
| Just a
ponieważ ma więcej niż jednego konstruktora. Nie możesz też pisać
newtype Book = Book Int Int
Ścisłość
Usunięcie konstruktora prowadzi do bardzo subtelnych różnic w ścisłości między nimi data i newtype. W szczególności datawprowadza typ, który jest „podnoszony”, co w istocie oznacza, że ma on dodatkowy sposób oceny do dolnej wartości. Ponieważ w środowisku wykonawczym nie ma dodatkowego konstruktoranewtype , ta właściwość nie zachowuje się.
Ten dodatkowy wskaźnik w Book(,) konstruktorze do pozwala nam wstawić dolną wartość.
W rezultacie newtypeidata mają nieco inne właściwości surowości, jak wyjaśniono w artykule Haskell wiki .
Rozpakowanie
Rozpakowywanie składników a nie ma sensu newtype, ponieważ nie ma konstruktora. Chociaż napisanie:
data T = T {-# UNPACK #-}!Int
zwracanie obiektu wykonawczego za pomocą Tkonstruktora i Int#komponentu. Wystarczy dostać nagie Intznewtype .
Referencje :