我写这篇文章有什么区别?

data Book = Book Int Int


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

最佳答案

好问题!

有几个主要区别。

表示形式

  • 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
    

    严格

    删除构造函数的事实导致datanewtype在严格性上存在一些非常细微的差异。特别是,data引入了一种“提升”类型,从本质上讲,它意味着它还有一种附加的方法可以求出底值。由于在运行时没有其他带有newtype的构造函数,因此该属性不成立。
    Book中的指向(,)构造函数的额外指针使我们可以输入一个底值。

    结果,newtypedata的严格性属性与explained in the Haskell wiki article略有不同。

    取消装箱

    因为没有构造函数,所以取消newtype的组件的装箱是没有意义的。虽然写是完全合理的:
    data T = T {-# UNPACK #-}!Int
    

    生成带有T构造函数和Int#组件的运行时对象。您只得到带有Int的裸newtype

    引用文献:
  • "Newtype" on the Haskell wiki
  • 关于严格性属性的
  • Norman Ramsey's answer

    关于haskell - Haskell中 `data`和 `newtype`之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5889696/

  • 10-10 08:34