在研究并行编程和随后的评估策略时,出现了thunks是否可变的问题。举个例子,假设我有以下代码:
foo = 1 + 2 -- Thunk
bar = foo `seq` foo -- Evaluates foo
在评估seq
评估bar
时调用foo
,为bar
提供正常的表单值3
。此评估是否也会影响foo
?也就是说,在评估foo
后,1+2
的价值是3
还是bar
?
答案 0 :(得分:8)
Haskell报告仅指定评估顺序为"non-strict",因此任何一种行为都符合标准。
然而,使用lazy("call by need")评估,其中涉及以一种让你所描述的“可变”的方式共享价值,提供了超过"call by name"的渐近改进(即,没有分享)。
因此,在GHC(可能是大多数其他合理的实现)中,foo
在您第一次强制执行后将变为3
。但是,标准并未规定这一点,您应该牢记这一点。
答案 1 :(得分:1)
foo
和bar
为Constant Applicative Forms,(引自链接):
...可以编译成一段将由其共享的图形 所有用途或一些共享代码将用一些覆盖自己 第一次评估图表。
这句话的第二部分对应于懒惰评估,其中foo
在评估bar
后将为3。第一部分更为通用(并未说明共享图形会发生什么),因此可以重新评估foo
。