You can, but it won't evaluate lazily:
def bin(s: String, n: Int): Stream[String] = {
if (s.length == n) {
println("got " + s) // for figuring out when it's evaluated
Stream(s)
} else {
val s0 = s + '0'
val s1 = s + '1'
bin(s0, n) ++ bin(s1, n)
}
}
For instance, when executing bin("", 2).take(2).foreach(println)
, you'll get the following output:
scala> bin("", 2).take(2).foreach(println)
got 00
got 01
got 10
got 11
00
01
If you don't mind using a TraversableView
you can use the conversion described here https://stackoverflow.com/a/3816012/257449. So then the code becomes:
def toTraversable[T]( func : (T => Unit) => Unit) = new Traversable[T] {
def foreach[X]( f : T => X) = func(f(_) : Unit)
}
def bin2(str: String, n: Int) = {
def recurse[U](s: String, f: (String) => U) {
if (s.length == n) {
println("got " + s) // for figuring out when it's evaluated
f(s)
} else {
recurse(s + '0', f)
recurse(s + '1', f)
}
}
toTraversable[String](recurse(str, _)) view
}
Then
scala> bin2("", 2).take(2).foreach(println)
got 00
00
got 01
01
got 10