Разница между `data` и`newtype` в Haskell

Какая разница, когда я пишу это?

data Book = Book Int Int

против

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

1 ответ

Решение

Отличный вопрос!

Есть несколько ключевых отличий.

Представление

  • 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, это свойство не имеет места.

Этот дополнительный указатель в Book в (,) Конструктор позволяет нам поставить нижнее значение в.

В следствии, newtype а также data имеют немного отличающиеся свойства строгости, как объяснено в статье на Haskell wiki.

Распаковка

Не имеет смысла распаковывать компоненты newtype, так как нет конструктора. Хотя вполне разумно написать:

data T = T {-# UNPACK #-}!Int

получая объект времени выполнения с T конструктор и Int# составная часть. Вы просто оголитесь Int с newtype,


Рекомендации:

Другие вопросы по тегам