Різниця між "даними" та "новим типом" в Хаскеллі


191

Яка різниця, коли я це пишу?

data Book = Book Int Int

проти

newtype Book = Book (Int, Int) -- "Book Int Int" is syntactically invalid

Ви повинні провести пошук, на це питання вже відповіли. stackoverflow.com/questions/2649305 / ...
tehman


Також пов’язано: використання для нового типу: stackoverflow.com/questions/991467/…
Дон Стюарт

25
Зверніть увагу, що newtype Book = Book Int Intце неправда. Ви можете, однак, newtype Book = Book (Int, Int)зазначити донів нижче.
Едвард КМЕТТ

Відповіді:


241

Чудове запитання!

Є кілька ключових відмінностей.

Представництво

  • А newtypeгарантія , що ваші дані будуть мати точно таке ж уявлення під час виконання, як тип , який ви укладаєте.
  • Поки dataдекларується абсолютно нова структура даних під час виконання.

Тож ключовим моментом тут є те, що конструкція для newtype файлу гарантовано буде стерта під час компіляції.

Приклади:

  • data Book = Book Int Int

дані

  • 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.


Список літератури :


2
Я все ще не думаю, що я щось пропущу, якби в Хаскелі не було «нового типу». Тонкі відмінності додають складності мові, яка мені не здається
гідною

14
Різниця дуже корисна з міркувань продуктивності. Оскільки конструктори нового типу стираються під час компіляції, вони не накладають штрафну ефективність виконання, яку робить конструктор даних. Але вони все одно дають вам всі переваги абсолютно виразного типу та будь-яких абстракцій, які ви хочете пов’язати з ним. Наприклад, є два різні способи, за допомогою якого тип даних списку може утворювати монаду. Один вбудований у мову, але якби ви хотіли скористатись іншим, шлях буде новий.
mightybyte

Чудове пояснення! Що я не розумію, якщо newtypeстирається після компіляції і час виконання використовує те саме представлення для старих і нових типів, як ми все ще зможемо визначити екземпляри як для старого, так і для нового типу? Як час виконання може зрозуміти, який екземпляр використовувати?
damluar

3
@damluar Усі типи стираються під час виконання, усі вони повністю вирішені під час компіляції, а під час компіляції newtypeявно ще не стираються.
крапка з комою

3
@damlaur У мене колись було те саме питання, що і у вас. Коли люди кажуть, що типи стираються, вони пропускають згадати, що одне слово ISN'T стерте, це слово пам'яті, яке використовується для пошуку словника, щоб вирішити, який метод екземпляра використовувати для даної частини даних. Люди стверджують, що це слово не є "типом", що, на мою думку, залежить від вашої точки зору, але там ви йдете.
Габріель Л.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.