过滤Scala流期间的StackOverflower错误

过滤Scala流期间的StackOverflower错误,scala,Scala,我试图用谓词过滤流,但当我试图将流转换为包含谓词返回false的元素的列表时,我收到一个错误 def machine(n:Int) = if (n==0) List(0) else List(n/2,n/3,n/4) def greater(n:Int) = machine(n).sum > n val d: Stream[Int] = 2 #:: d.map(_+1).filterNot(greater) scala> d.take(11).toList res41: List

我试图用谓词过滤流,但当我试图将流转换为包含谓词返回
false
的元素的列表时,我收到一个错误

def machine(n:Int) = if (n==0) List(0) else List(n/2,n/3,n/4)
def greater(n:Int) = machine(n).sum > n

val d: Stream[Int] = 2 #:: d.map(_+1).filterNot(greater)

scala> d.take(11).toList
res41: List[Int] = List(2,3,4,5,6,7,8,9,10,11)

//12 is the first number for which greater will return true
scala> d.take(12).toList
//Returns a ton of scala.collection.immutable.Stream errors

有人能给我解释一下这里到底出了什么问题吗?谢谢。

代码以递归方式工作。当流中的项用完时,递归将一无所获,最终会耗尽堆栈空间。(由于过滤掉了所有较大的项目,当您请求的项目超过流中可能的项目数时,您希望发生什么?您应该得到堆栈溢出或非终止(挂起),对吗?

当然,挂起是正确的行为,但我不希望它在过滤元素的长时间运行中消耗线性堆栈。@MyseriousDan-惰性数据结构并不总是以您期望的方式消耗堆栈,至少如果以天真的方式实现的话。我意识到(我来自Haskell land)但在我看来,以允许的方式使用库函数中的堆栈溢出是错误的。使用线性堆栈几乎从来都不是正确的做法。@MyseriousDan-可能不是。在这方面,库实现可能需要大量的工作。(不过,如果您可以不受影响的话,使用堆栈的速度要快得多。)