列表foldRight始终使用foldLeft?

时间:2013-10-23 17:05:22

标签: scala

我刚看了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多个堆栈帧?

1 个答案:

答案 0 :(得分:17)

foldLeft是尾递归的,reverse根本不是递归的:这种实现确保了常量的内存使用。 foldRight未在foldLeft方面实现时,不是尾递归,这使得大量数据不安全。

注意:可能有一些方法可以使foldRight尾递归,但我能想到的所有东西都需要在列表的末尾附加内容,这意味着完整地遍历它。如果你打算这样做,最好使用foldLeft并反转结果,它会在整个列表中涉及更少的完整迭代。