I defined a function to return Fibonacci stream as follows:
def fib:Stream[Int] = { Stream.cons(1, Stream.cons(2, (fib zip fib.tail) map {case (x, y) => println("%s + %s".format(x, y)); x + y})) }
The functions work ok but it looks inefficient (see the output below)
scala> fib take 5 foreach println 1 2 1 + 2 3 1 + 2 2 + 3 5 1 + 2 1 + 2 2 + 3 3 + 5 8
So, it looks like the function calculates the n-th fibonacci number from the very beginning. Is it correct? How would you fix it?
That is because you have used a def
. Try using a val
:
lazy val fib: Stream[Int]
= 1 #:: 2 #:: (fib zip fib.tail map { case (x, y) => x + y })
Basically a def
is a method; in your example you are calling the method each time and each time the method call constructs a new stream. The distinction between def
and val
has been covered on SO before, so I won't go into detail here. If you are from a Java background, it should be pretty clear.
This is another nice thing about scala; in Java, methods may be recursive but types and values may not be. In scala both values and types can be recursive.
You can do it the other way:
lazy val fibs = {
def f(a: Int, b: Int): Stream[Int] = a #:: f(b, a + b)
f(0, 1)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With