Ответ 1
Отличный вопрос!
Существует несколько ключевых отличий.
Представление
- A
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
работает только при обертке типа данных с помощью одного конструктора. Нет понятия "алгебраических" новых типов. То есть вы не можете написать эквивалент newtype, скажем,
data Maybe a = Nothing
| Just a
поскольку он содержит более одного конструктора. Вы также не можете написать
newtype Book = Book Int Int
Строгость
Тот факт, что конструктор стирается, приводит к некоторым очень тонким различиям в строгости между data
и newtype
. В частности, data
вводит тип, который "снят", что означает, по существу, что у него есть дополнительный способ оценить нижнее значение. Поскольку во время выполнения с newtype
нет дополнительного конструктора, это свойство не выполняется.
Этот дополнительный указатель в конструкторе Book
to (,)
позволяет нам установить нижнее значение.
В результате newtype
и data
имеют несколько иные свойства строгости, поскольку объясняется в статье Wiki Haskell.
Распаковка
Не имеет смысла распаковывать компоненты newtype
, так как нет конструктора. Хотя вполне разумно писать:
data T = T {-# UNPACK #-}!Int
дает объект времени выполнения с конструктором T
и компонентом Int#
. Вы получите только Int
с newtype
.
Литература:
- "Newtype" в вики Haskell
- Норман Рамси отвечает о свойствах строгости