带有严格注释的“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 的值。

我认为这是严格 datanewtype 之间唯一的运行时差异。 存在一些静态差异,例如一些 GHC 扩展只影响 newtypeCoercible 等,但在运行时这两种类型是同构的(但模式匹配操作不同,如上所示)。