为什么 foldr 应用于两个参数都严格的函数不会导致堆栈溢出?
Why does foldr applied to a function strict in both arguments not cause a stack overflow?
我想知道为什么这个表达式不会导致 GHCi 中的堆栈溢出:
foldr (+) 0 [1..5000000] -- 12500002500000
显然,(+)
的两个参数都是严格的,因此必须立即遍历整个列表,懒惰也无济于事。
我的第一个想法是编译器会将(+)
识别为关联运算并将其转换为尾递归。
但是,以下操作也有效:
foldr (-) 0 [1..5000000] -- -2500000
这里发生了什么?
GHC 最新的运行时系统让它的堆栈动态增长。尝试限制它,你会看到你的堆栈溢出:
% ghci +RTS -K512K
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
Prelude> foldr (+) 0 [1..5000000]
*** Exception: stack overflow
我想知道为什么这个表达式不会导致 GHCi 中的堆栈溢出:
foldr (+) 0 [1..5000000] -- 12500002500000
显然,(+)
的两个参数都是严格的,因此必须立即遍历整个列表,懒惰也无济于事。
我的第一个想法是编译器会将(+)
识别为关联运算并将其转换为尾递归。
但是,以下操作也有效:
foldr (-) 0 [1..5000000] -- -2500000
这里发生了什么?
GHC 最新的运行时系统让它的堆栈动态增长。尝试限制它,你会看到你的堆栈溢出:
% ghci +RTS -K512K
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
Prelude> foldr (+) 0 [1..5000000]
*** Exception: stack overflow