В 2.8 есть защищенный метод с именем tailDefined
, который вернет false, когда вы попадете в точку в потоке, которая еще не была оценена.
Это не слишком полезно (если вы не хотите писать собственный класс Stream
), за исключением того, что Cons
сам делает метод общедоступным. Я не уверен, почему это защищено в потоке, а не в минусах - я думаю, что один или другой может быть ошибкой. Но сейчас, по крайней мере, вы можете написать такой метод (запись функционального эквивалента оставлена читателю в качестве упражнения):
def streamEvalLen[T](s: Stream[T]) = {
if (s.isEmpty) 0
else {
var i = 1
var t = s
while (t match {
case c: Stream.Cons[_] => c.tailDefined
case _ => false
}) {
i += 1
t = t.tail
}
i
}
}
Здесь вы можете увидеть это в действии:
scala> val s = Stream.iterate(0)(_+1)
s: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> streamEvalLen(s)
res0: Int = 1
scala> s.take(3).toList
res1: List[Int] = List(0, 1, 2)
scala> s
res2: scala.collection.immutable.Stream[Int] = Stream(0, 1, 2, ?)
scala> streamEvalLen(s)
res3: Int = 3