Haskell中`data`和`newtype`之间的区别

时间:2011-05-04 20:50:49

标签: haskell types type-systems newtype

写这篇文章有什么区别?

data Book = Book Int Int

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

1 个答案:

答案 0 :(得分:219)

很棒的问题!

有几个关键的区别。

<强>表示

  • newtype保证您的数据在运行时与您包装的类型具有完全相同的表示。
  • 虽然data在运行时声明了一个全新的数据结构。

所以这里的关键点是newtype的构造保证在编译时被擦除。

示例:

  • data Book = Book Int Int

data

  • newtype Book = Book (Int, Int)

newtype

请注意它与(Int,Int)具有完全相同的表示形式,因为Book构造函数已被删除。

  • data Book = Book (Int, Int)

data tuple

Book中没有其他newtype构造函数。

  • data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int

enter image description here

没有指针!这两个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。{/ p>


参考

相关问题