我刚看了foldRight()
的{{1}}实现。
override def reverse: List[A] = {
var result: List[A] = Nil
var these = this
while (!these.isEmpty) {
result = these.head :: result
these = these.tail
}
result
}
override def foldRight[B](z: B)(op: (A, B) => B): B =
reverse.foldLeft(z)((right, left) => op(left, right))
据我了解,在foldRight
上调用List
会导致调用theList.reverse.foldLeft(...)
。
使用List.foldRight
实现foldLeft
是为了利用单个堆栈帧而不是使用foldLeft
多个堆栈帧?
答案 0 :(得分:17)
foldLeft
是尾递归的,reverse
根本不是递归的:这种实现确保了常量的内存使用。 foldRight
未在foldLeft
方面实现时,不是尾递归,这使得大量数据不安全。
注意:可能有一些方法可以使foldRight
尾递归,但我能想到的所有东西都需要在列表的末尾附加内容,这意味着完整地遍历它。如果你打算这样做,最好使用foldLeft
并反转结果,它会在整个列表中涉及更少的完整迭代。