我对这篇好文章有疑问:
https://wiki.haskell.org/Foldr_Foldl_Foldl'
当他们在foldl
示例中达到此步骤时:
let z1 = 0 + 1
z2 = z1 + 2
z3 = z2 + 3
z4 = z3 + 4
...
z999997 = z999996 + 999997
z999998 = z999997 + 999998
z999999 = z999998 + 999999
z1000000 = z999999 + 1000000
in z1000000
0
,1
,2
,3
,......,999999
和1000000
的提及实际上是数字他们自己,还是他们真的只是这些数字的占位符 - 在计算后期(实际需要实际添加时需要实际数字)时,用实际数字代替的占位符?
我希望你理解我的意思。
答案 0 :(得分:2)
首先,讨论的重点完全独立于此细节,因此,就讨论而言,您可以将它们视为完全评估。
其次"一步一步"他们给出的描述是 not 正式定义的缩减,保证完全按照书面形式发生。他们只是给出想法在这种情况下会发生什么,所以对此进行挑剔是没有用的。
现在实际上他们可以无法完全评估。对于[n..m]
的调用,enumFromTo n m
语法实际上是语法糖。根据{{1}}的评估方式,这些数字实际上可能是enumFromTo
,1
,1+1
等。
然而,即使在做的时候,他们的观点仍然存在:
(1+1)+1
veryBigList `deepseq` foldl (+) 0 veryBigList
确保deepseq
在veryBigList
发生之前完全评估foldl
。问题在于,即使在这种情况下,foldl
也会造成巨大的打击。
此外,表示这些数字的thunk 可能依赖于之前数字的thunk,就好像它们是:
let n1 = 1
z1 = 0 + n1
n2 = n1 + 1
z2 = z1 + n2
n3 = n2 + 1
z3 = z2 + n3
...
in ...
这意味着,如果您使用zi
thunk解决了问题,那么自动解决ni
thunks的问题,因为它们是在时间,一旦你评估了thunk ni
,它就不会被重新评估以计算n(i+1)
。
这意味着即使是那些thunk也会有不变的大小。
所以,重复第一点,在讨论这个讨论时,你不应该担心这个问题。