Haskell中`data`和`newtype`之间的区别
我写这个有什么不同?
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
严格
该构造被删除,这一事实导致之间严格一些很细微的差别data和newtype 。 特别是, data引入了“提升”的类型,实质上意味着它有一种额外的方式来评估最低价值。 由于在运行时没有使用newtype附加构造函数,因此此属性不成立。
Book to (,)构造函数中的额外指针允许我们将底部值放入。
其结果是, newtype和data具有略微不同的严格性,因为Haskell的wiki文章中所说明的。
拆箱
它没有意义拆箱一的组件newtype ,因为没有构造函数。 尽管写作是完全合理的:
data T = T {-# UNPACK #-}!Int
产生一个带T构造函数的运行时对象和一个Int#组件。 你只需要用newtype得到一个newtype Int 。
参考文献:
