我写这篇文章有什么区别?
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
中的指向(,)
构造函数的额外指针使我们可以输入一个底值。结果,
newtype
和data
的严格性属性与explained in the Haskell wiki article略有不同。取消装箱
因为没有构造函数,所以取消
newtype
的组件的装箱是没有意义的。虽然写是完全合理的:data T = T {-# UNPACK #-}!Int
生成带有
T
构造函数和Int#
组件的运行时对象。您只得到带有Int
的裸newtype
。引用文献:
关于haskell - Haskell中 `data`和 `newtype`之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5889696/