When writing a function operating on Stream
(s), there are different notions of recursion. The first simple sense is not recursive on the compiler level, since t
The problem, as you've hinted, is that in the code you pasted the filterHelp function keeps the head (hence your solution removing it).
Best answer is to simply avoid this surprising behaviour, use Scalaz EphemeralStream and see it both not oom and run significantly faster as its far nicer to the gc. Its not always as simple to work with e.g. head is a () => A not A, no extractors etc, but its all geared to one objective, reliable stream usage.
Your filterHelper function generally doesn't have to care about if it keeps a reference around:
import scalaz.EphemeralStream
@scala.annotation.tailrec
def filter[A](s: EphemeralStream[A], f: A => Boolean): EphemeralStream[A] =
if (s.isEmpty)
s
else
if (f(s.head()))
EphemeralStream.cons(s.head(), filterHelp(s.tail() , f) )
else
filter(s.tail(), f)
def filterHelp[A](s: EphemeralStream[A], f: A => Boolean) =
filter(s, f)
def s1 = EphemeralStream.range(1, big)
I'd go so far as to say that unless you have a compelling reason to use Stream (other library dependencies etc) then just stick to EphemeralStream, there are far less surprises there.