他のポスターは良い答えを出しました、そして私は彼らがすでに言ったことを繰り返しません。質問でScalaの例を挙げたので、Scala固有の例を示します。Tricksがすでに述べたように、スタックフレームを保持する必要がfoldRight
あります。これはリストの長さであり、これはスタックオーバーフローにつながる可能性があります。末尾再帰でさえ、これからあなたを救うことはできません。n-1
n
AList(1,2,3).foldRight(0)(_ + _)
は次のようになります。
1 + List(2,3).foldRight(0)(_ + _) // first stack frame
2 + List(3).foldRight(0)(_ + _) // second stack frame
3 + 0 // third stack frame
// (I don't remember if the JVM allocates space
// on the stack for the third frame as well)
にList(1,2,3).foldLeft(0)(_ + _)
減少しますが:
(((0 + 1) + 2) + 3)
これは、の実装でList
行われるように、繰り返し計算できます。
Scalaとして厳密に評価された言語では、afoldRight
は大きなリストのスタックを簡単に爆破できますが、そうでfoldLeft
はありません。
例:
scala> List.range(1, 10000).foldLeft(0)(_ + _)
res1: Int = 49995000
scala> List.range(1, 10000).foldRight(0)(_ + _)
java.lang.StackOverflowError
at scala.List.foldRight(List.scala:1081)
at scala.List.foldRight(List.scala:1081)
at scala.List.foldRight(List.scala:1081)
at scala.List.foldRight(List.scala:1081)
at scala.List.foldRight(List.scala:1081)
at scala.List.foldRight(List.scala:1081)
at scala.List.foldRight(List.scala:1081)
at scala.List.foldRight(List.scala:1081)
at scala.List.foldRig...
したがって、私の経験則は、特定の結合性を持たない演算子の場合foldLeft
、少なくともScalaでは常にを使用することです。それ以外の場合は、回答に記載されている他のアドバイスを参考にしてください;)。