I have a Stream
of data and I want to throw everything away except for the final n elements. If the input doesn't have enough elements then the resulting stream is padded with None
. This is what I came up with:
def lastN[T](in: Stream[T], len: Int): Stream[Option[T]] =
in.foldLeft(Vector.fill[Option[T]](len)(None))(_.tail :+ Option(_)).to[Stream]
I chose Vector
for the internal buffer because of its tail
and append
performance characteristics.
This all works fine. Perhaps there's a better way? [Note: There's always a better way.]
But suppose Iterator
is a more appropriate representation of the input data? No problem, just replace the 3 mentions of Stream
with Iterator
and it all works.
OK, so why not either/both?
I was hoping I could do something like this:
import scala.language.higherKinds
def lastN[T, C[U] <: TraversableOnce[U] ](in: C[T], len: Int): C[Option[T]] =
in.foldLeft(Vector.fill[Option[T]](len)(None))(_.tail :+ Option(_)).to[C]
Alas, no go.
error: Cannot construct a collection of type C[Option[T]] with elements of type Option[T] based on a collection of type Nothing.
I've tried futzing with CanBuildFrom
directly but I'm just not coming up with the magic formula.