带有严格注释的“newtype”和“data”之间的区别
Difference between `newtype` and `data` with a strictness annotation
这段代码如何
data D = D { _d :: ![P] } -- Note the strictness annotation!
与此比较
newtype D = D { _d :: [P] }
一个 answer to a related question 说:
the main difference between data and newtype is that with data is that data constructors are lazy while newtype is strict
当 data
版本有严格注释时,这种差异是如何产生的?
(问题基于我偶然发现的真实代码)
例如,
case undefined of
D d -> "hello"
对于 data
类型(严格或不严格)会出错,但对于新类型会计算为 "hello"
。
这是因为,在运行时,应用 newtype
构造函数或对其进行模式匹配相当于没有操作。甚至不强求我们 case
的价值。
相比之下,data
构造函数上的模式匹配总是强制我们 case
的值。
我认为这是严格 data
和 newtype
之间唯一的运行时差异。
存在一些静态差异,例如一些 GHC 扩展只影响 newtype
、Coercible
等,但在运行时这两种类型是同构的(但模式匹配操作不同,如上所示)。
这段代码如何
data D = D { _d :: ![P] } -- Note the strictness annotation!
与此比较
newtype D = D { _d :: [P] }
一个 answer to a related question 说:
the main difference between data and newtype is that with data is that data constructors are lazy while newtype is strict
当 data
版本有严格注释时,这种差异是如何产生的?
(问题基于我偶然发现的真实代码)
例如,
case undefined of
D d -> "hello"
对于 data
类型(严格或不严格)会出错,但对于新类型会计算为 "hello"
。
这是因为,在运行时,应用 newtype
构造函数或对其进行模式匹配相当于没有操作。甚至不强求我们 case
的价值。
相比之下,data
构造函数上的模式匹配总是强制我们 case
的值。
我认为这是严格 data
和 newtype
之间唯一的运行时差异。
存在一些静态差异,例如一些 GHC 扩展只影响 newtype
、Coercible
等,但在运行时这两种类型是同构的(但模式匹配操作不同,如上所示)。