我已经阅读了很多关于弱头正常形式和序列的内容。但是我仍然无法想象 Haskell 评估顺序背后的逻辑
演示何时以及如何使用的常见示例,但我仍然不明白常见示例如何
foldl (+) 0 [1..5000000]
可能导致堆栈溢出。而另一个折叠定义使用seq
不
foldl' _ a [] = a
foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs
foldl' (+) 0 [0..5000000]
从我读过的对 seq 的解释中,作者非常小心地阐明了以下内容:
- 的第一个参数
seq
不能保证在第二个参数之前被评估 - 的第一个参数
seq
只会被评估为弱头范式 - 的第一个参数的评估
seq
只会在第二个评估为 WHNF 时发生
那么,如果以上是正确的(是吗?)那么为什么不foldl'
溢出foldl
呢?
当我们减少一个步骤时,它不应该是这样的吧?
foldl' (+) 0 (1:xs) = let a' = (+) 0 1 in a' `seq` foldl' (+) a' xs
在上面,第二个参数seq
不在 WHNF 中,因为需要完成一个函数应用程序。seq
我们是否保证在到达第二个参数的 WHNF 之前评估这里的第一个参数?