今天在调查一个错误时,我注意到在具有 50 个(Int, Int)
元组的流上调用 sumr
永远不会完成,但它在较小的流上会完成。在较大的流上调用.toList
也首先完成。
这是在大型流上调用sumr
时的预期行为吗?它没有评估流以完成,还是其他原因导致这种情况?
scala> val strSmall = Stream((1,1),(2,4),(3,9),(4,16),(5,25))
strSmall: scala.collection.immutable.Stream[(Int, Int)] = Stream((1,1), ?)
scala> val strBig = Stream((1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (0,1), (1,0), (1,0), (1,0), (1,0), (0,1), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (1,0), (0,1), (1,0), (1,0), (1,0), (1,0), (1,0))
strBig: scala.collection.immutable.Stream[(Int, Int)] = Stream((1,0), ?)
scala> strSmall.sumr
res3: (Int, Int) = (15,55)
scala> strBig.toList.sumr
res4: (Int, Int) = (47,3)
scala> strBig.sumr
<!-- never completes -->
sumr
是按照foldRight
实现的:
final def sumr(implicit A: Monoid[A]): A = F.foldRight(self, A.zero)(A.append)
foldRight
并不总是尾递归的,因此如果集合太长,可能会溢出堆栈。请参阅为什么 foldRight 和 reduceRight 不是尾递归?有关何时正确或不正确的更多讨论。