组合函数导致StackOverflow

时间:2014-03-27 01:55:02

标签: scala

Functional Programming in Scala列出了以下关于合成函数如何导致StackOverflowError的示例。

scala> val f = (x: Int) => x
f: Int => Int = <function1>

scala> val g = List.fill(100000)(f).foldLeft(f)(_ compose _)
g: Int => Int = <function1>

scala> g(42)
java.lang.StackOverflowError

正如本书所解释的那样,g是一个复合函数,它有100,000个函数,每个函数都调用下一个函数。

由于foldLeft是尾递归的,为什么会出现StackOverflowError?如果有的话,尾递归和StackOverflow是如何相关的?

当(扩展)(B, A) => BfoldLeft的第二个参数((acc, elem) => acc.compose(elem))时,每个折叠步骤不会导致只编写2个函数吗?

2 个答案:

答案 0 :(得分:6)

  

由于foldLeft是尾递归的,为什么会出现StackOverflowError?如果有的话,尾递归和StackOverflow是如何相关的?

     

当(扩展时)第二个参数(B,A)=&gt; foldLeft的B,((acc,elem)=&gt; acc.compose(elem)),每个折叠步骤不会只组成2个函数吗?

请注意,折叠本身(即行val g = ...)不会溢出堆栈。但是,g最终被有效地定义为f(f(...(x))),因此您需要100000个堆栈帧来评估显然会溢出的g(42)

答案 1 :(得分:5)

这不是因为foldLeftcompose本身。这是因为g(x) = f(f(f(...(x)))