Чудове запитання!
Є кілька ключових відмінностей.
Представництво
- А
newtypeгарантія , що ваші дані будуть мати точно таке ж уявлення під час виконання, як тип , який ви укладаєте.
- Поки
dataдекларується абсолютно нова структура даних під час виконання.
Тож ключовим моментом тут є те, що конструкція для newtype файлу гарантовано буде стерта під час компіляції.
Приклади:

newtype Book = Book (Int, Int)

Зауважте, як воно має точно таке ж представлення, як а (Int,Int), оскільки Bookконструктор стирається.
data Book = Book (Int, Int)

Має додатковий Bookконструктор, який не присутній у newtype.
data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int

Без покажчиків! Два Intполя - це поля без коробки у Bookконструкторі.
Алгебраїчні типи даних
Через це потрібно стерти конструктор, працює newtypeлише при обгортанні типу даних одним конструктором . Не існує поняття "алгебраїчні" новітипи. Тобто ви не можете написати еквівалент нового типу, скажімо,
data Maybe a = Nothing
| Just a
оскільки він має більше одного конструктора. Також не можна писати
newtype Book = Book Int Int
Строгість
Той факт, що конструктор стирається, призводить до деяких дуже тонких відмінностей у строгості між dataі newtype. Зокрема, dataвводиться тип, який "піднятий", тобто по суті, що він має додатковий спосіб оцінити до нижнього значення. Оскільки в процесі виконання немає додаткових конструкторів newtype, ця властивість не втримується.
Цей додатковий вказівник у конструкторі Bookto (,)дозволяє нам встановити нижнє значення.
Як результат, newtypeі dataмають дещо інші властивості строгості, як це пояснено у статті wiki wiki .
Розпакування
Немає сенсу розблокувати компоненти компонента newtype, оскільки конструктора немає. Хоча писати:
data T = T {-# UNPACK #-}!Int
отримання об'єкта виконання з Tконструктором та Int#компонентом. Ви просто отримати голий Intз newtype.
Список літератури :