Scala:列表中的不同foldRight实现
我刚刚发现scala(我在2.12上)为不可变列表和可变列表提供了完全不同的foldRight实现 不可变列表(list.scala): 可变列表(LinearSeqOptimized.scala): 现在我只是好奇。Scala:列表中的不同foldRight实现,scala,Scala,我刚刚发现scala(我在2.12上)为不可变列表和可变列表提供了完全不同的foldRight实现 不可变列表(list.scala): 可变列表(LinearSeqOptimized.scala): 现在我只是好奇。 你能解释一下为什么它的实现如此不同吗?在列表中的覆盖似乎覆盖了线性化的中的foldRight。linearseq中的实现得到了优化 def foldRight[B](z: B)(@deprecatedName('f) op: (A, B) => B): B = if (
你能解释一下为什么它的实现如此不同吗?在
列表中的覆盖似乎覆盖了线性化的中的foldRight
。linearseq中的实现得到了优化
def foldRight[B](z: B)(@deprecatedName('f) op: (A, B) => B): B =
if (this.isEmpty) z
else op(head, tail.foldRight(z)(op))
看起来就像你的一般理论书中对foldRight的经典定义一样。但是,正如在中所注意到的,此实现不是堆栈安全的(对于长列表抛出意外的stackoverflowerrror
)。因此,它被中的堆栈安全reverse.foldLeft
所取代。foldLeft
是堆栈安全的,因为它是由while循环实现的:
def foldLeft[B](z: B)(@deprecatedName('f) op: (B, A) => B): B = {
var acc = z
var these = this
while (!these.isEmpty) {
acc = op(acc, these.head)
these = these.tail
}
acc
}
这很有希望解释为什么它在列表中被覆盖。它没有解释为什么它没有在其他类中被重写。我想这仅仅是因为可变数据结构的使用频率较低,而且使用方式也非常不同(在构建不可变数据结构的过程中,通常作为缓冲区和累加器)
提示:Github上的每个文件的右上角都有一个dull
按钮,因此您可以随时跟踪更改的时间、更改的人以及更改的原因。这很有帮助!谢谢@正常我认为,从长远来看,带有git-burn
的提示比答案本身更有用。谢谢你的提问,我以前从未注意过@deprecatedName
注释:]我完全同意)谢谢你的提示。
def foldRight[B](z: B)(@deprecatedName('f) op: (A, B) => B): B =
if (this.isEmpty) z
else op(head, tail.foldRight(z)(op))
def foldLeft[B](z: B)(@deprecatedName('f) op: (B, A) => B): B = {
var acc = z
var these = this
while (!these.isEmpty) {
acc = op(acc, these.head)
these = these.tail
}
acc
}