Haskell中`data`和`newtype`之间的区别 [英] Difference between `data` and `newtype` in Haskell

查看:610
本文介绍了Haskell中`data`和`newtype`之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



  data Book = Book Int Int 

newtype Book = Book(Int,Int) - Book Int Int在语法上无效


解决方案

伟大的问题!



有几个关键区别。



代表




  • newtype 可确保您的数据完全符合在运行时使用相同的表示形式,作为您打包的类型。

  • data 在运行时声明一个全新的数据结构。 >


所以关键在于 newtype 的结构保证被擦除在编译时。



示例:


  • 数据Book = Book Int Int






  • newtype Book = Book(Int,Int)



(Int,Int)具有完全相同的表示形式,因为<$
$ b




  • 数据Book = Book(Int ,Int)





Book 构造函数不存在于 newtype




What is the difference when I write this?

data Book = Book Int Int

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

解决方案

Great question!

There are several key differences.

Representation

  • A newtype guarantees that your data will have exactly the same representation at runtime, as the type that you wrap.
  • While data declares a brand new data structure at runtime.

So the key point here is that the construct for the newtype is guaranteed to be erased at compile time.

Examples:

  • data Book = Book Int Int

  • newtype Book = Book (Int, Int)

Note how it has exactly the same representation as a (Int,Int), since the Book constructor is erased.

  • data Book = Book (Int, Int)

Has an additional Book constructor not present in the newtype.

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

No pointers! The two Int fields are unboxed word-sized fields in the Book constructor.

Algebraic data types

Because of this need to erase the constructor, a newtype only works when wrapping a data type with a single constructor. There's no notion of "algebraic" newtypes. That is, you can't write a newtype equivalent of, say,

data Maybe a = Nothing
             | Just a

since it has more than one constructor. Nor can you write

newtype Book = Book Int Int

Strictness

The fact that the constructor is erased leads to some very subtle differences in strictness between data and newtype. In particular, data introduces a type that is "lifted", meaning, essentially, that it has an additional way to evaluate to a bottom value. Since there's no additional constructor at runtime with newtype, this property doesn't hold.

That extra pointer in the Book to (,) constructor allows us to put a bottom value in.

As a result, newtype and data have slightly different strictness properties, as explained in the Haskell wiki article.

Unboxing

It doesn't make sense to unbox the components of a newtype, since there's no constructor. While it is perfectly reasonable to write:

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

yielding a runtime object with a T constructor, and an Int# component. You just get a bare Int with newtype.


References:

这篇关于Haskell中`data`和`newtype`之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆