特征中定义的Scala尾递归流处理器函数保持对流头的引用

ron*_*ron 10 functional-programming scala stream

在以下情况

trait T {

 @tailrec
 def consume[A](as: Stream[A]): Unit = {
    if (as.isEmpty) ()
    else consume(as.tail)
  }
 }

object O extends T
Run Code Online (Sandbox Code Playgroud)

主叫O.consume(Range(1, N).toStream)N足够大的,程序将运行的存储器,或者至少将消耗O(N),而不是所需要的O(1).

ron*_*ron 11

为特征生成尾递归方法.特征扩展器中的方法条目(这里O)将调用转发给特征的方法,但是这样做时,它保持对流的头部的引用.

因此该方法是尾递归的,但仍无法释放内存.补救措施:不要直接在对象中定义特征中的流函数.

另一种选择是scalaz EphemeralStream,它包含对流头部和尾部的弱引用,并根据需要重新计算它们.