弱首标的形式和评价顺序

我读了很多弱头正常形式和seq。 但是我仍然很难想象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的第一个参数只会被评估为弱头标准形式
  • 只有当第二个参数被评估为WHNF时,才会对seq的第一个参数进行评估
  • 所以,如果以上是正确的(是吗?),那么为什么foldl'不像foldl那样溢出?

    当我们减少一步时,它不应该看起来像这样,对吗?

    foldl' (+) 0 (1:xs) = let a' = (+) 0 1 in a' `seq` foldl' (+) a' xs
    

    在上面, seq的第二个参数不在WHNF中,因为有一个函数应用程序需要完成。 在我们达到第二个参数的WHNF之前,我们是否保证评估seq的第一个参数?


  • seq的第一个参数不保证在第二个参数不被保证之前被评估,但是编译器会尝试并且通常在阻止thunk建立的时候这样做。 这种情况不适用于并行性,因此需要pseq - 但对于foldl' ,这并不相关。
  • seq的第一个参数只会被评估为弱头正常形式是的,但对于内置的数字类型WHNF = NF。
  • seq的第一个参数的评估只有在第二个评估为WHNF时才会发生。事实上,这经常会导致混淆。 但是in a' `seq` foldl' fa' xs表示如果您请求任何结果,它将触发seq 。 当我们减少一步时,它不应该看起来像这样,对吗? ... seq的第二个参数不在WHNF中正是这就是强制seq原因,因为要评估foldl' (+) 0 (1:xs)您需要foldl' (+) a' xs a'xs为WHNF, seq确保这不会发生在a' WHNF a'之前。
  • 链接地址: http://www.djcxy.com/p/7441.html

    上一篇: Weak head normal form and order of evaluation

    下一篇: strict and lazy differ?