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

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

问题描述

我写这个有什么不同?

data Book = Book Int Int

对比

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

推荐答案

好问题!

有几个主要区别.

代表

  • newtype 保证您的数据在运行时具有与您包装的类型完全相同的表示.
  • 虽然 data 在运行时声明了一个全新的数据结构.
  • 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.

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

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

示例:

  • data Book = Book Int Int

  • newtype Book = Book (Int, Int)

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

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

  • data Book = Book (Int, Int)

具有 newtype 中不存在的附加 Book 构造函数.

Has an additional Book constructor not present in the newtype.

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

没有指针!两个 Int 字段是 Book 构造函数中未装箱的字大小的字段.

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

代数数据类型

由于需要擦除构造函数,newtype 仅在用单个构造函数包装数据类型时才有效.没有代数"新类型的概念.也就是说,你不能写一个 newtype 等价于,比如,

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

严格

构造函数被擦除的事实导致了datanewtype 之间在严格性上的一些非常细微的差异.特别是,data 引入了一种提升"的类型,本质上,这意味着它有一种额外的方法来评估底部值.由于 newtype 在运行时没有额外的构造函数,所以这个属性不成立.

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.

Book 中指向 (,) 构造函数的额外指针允许我们放入一个底部值.

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

因此,newtypedata 的严格性属性略有不同,如 在 Haskell wiki 文章中解释.

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

拆箱

拆箱 newtype 的组件没有意义,因为没有构造函数.虽然这样写是完全合理的:

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

使用 T 构造函数和 Int# 组件生成运行时对象.你只需要一个带有 newtypeInt.

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

参考文献:

  • "Newtype" on the Haskell wiki
  • Norman Ramsey's answer about the strictness properties

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

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