【问题标题】:Difference between `newtype` and `data` with a strictness annotation带有严格注释的`newtype`和`data`之间的区别
【发布时间】:2019-04-22 19:01:57
【问题描述】:

这段代码如何

data D = D { _d :: ![P] } -- Note the strictness annotation!

比较一下

newtype D = D { _d :: [P] }

answer to a related question 说:

data 和 newtype 的主要区别在于 data 的构造函数是惰性的,而 newtype 是严格的

data 版本有严格注解时,这种差异如何发挥作用?

(问题基于我偶然发现的真实代码)

【问题讨论】:

    标签: haskell lazy-evaluation newtype


    【解决方案1】:

    例如,

    case undefined of
       D d -> "hello"
    

    对于data 类型(严格或不严格)将出错,但对于新类型将评估为"hello"

    这是因为,在运行时,应用newtype 构造函数,或对其进行模式匹配对应于无操作。甚至没有强加我们case 的价值。

    相比之下,data 构造函数上的模式匹配总是强制我们使用 case 的值。

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

    【讨论】:

    • 那么如果不做这样的模式匹配,那两者绝对没有区别?
    • 新类型没有的严格数据应该会有轻微的内存开销,但我不记得 GHC 是否可以优化它。
    • @yairchu 我想是的。正如 DarthFennec 指出的那样,严格数据的内存开销很小。请注意,“如果没有这样的模式匹配”可能是一个很大的“如果”——模式匹配是数据类型的一切。例如。 case expensiveFunction 23 of D d -> ... 立即为大数据执行昂贵的计算,可能会根据... 在内存中长时间保留一个长列表d。使用新类型,该列表将被懒惰地绑定,并且仅在 ... 要求时(并且如果)在之后生成。
    猜你喜欢
    • 2011-08-18
    • 2012-06-25
    • 2018-07-04
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 2016-12-28
    • 2017-07-05
    • 1970-01-01
    相关资源
    最近更新 更多