I was wondering if there is a better way to write recursive loops in scala.
def fib(n: Int) = {
def loop(a: BigInt = 0, b: BigInt = 1, n: Int = n): BigInt = {
if(n==0) a
else loop(b, a+b, n-1)
}
loop()
}
I could write it like this
def fib(n: Int, a: BigInt = 0, b: BigInt = 1): BigInt = {
if(n==0) a
else fib(n-1, b, a+b)
}
but then a and b would be exposed and not encapsulated inside the method anymore.
Recursion refers to a general method that involves defining a solution or object in terms of itself. Recursive functions refer to a kind of function where the definition of a function includes calling the function itself.
The use of recursion is a more functional approach to writing loops than using a for loop. Scala highly encourages the use of functional loops. Recursive algorithms can sometimes create extremely deep call stacks and exhaust the stack space.
A recursive function is said to be tail-recursive if the recursive call is the last operation performed by the function. There is no need to keep a record of the previous state. In Scala, you can use @tailrec to check if the recursion is tail-recursive or not. The annotation is available in the scala.
If you heard about loops in Scala, try to forget them. Try to do without them. Instead of asking “how can I loop through this”, ask “how can I transform this”. Take this one principle to heart and you'll be ahead of many Scala programmers already.
Note that you can often use foldLeft
or foldRight
in such situations:
def fib(n: Int) = (1 to n).foldLeft((BigInt(0),BigInt(1)))((p,_)=>(p._2,p._1+p._2))._1
[Edit]
Another approach would be an iterator-based solution:
def fib = Iterator.iterate((0,1)){case (x,y) => (y,x+y)}.map(_._1)
This generates an infinite amount of fibonacci numbers, but you can simply take as many as you want from it, e.g. fib.take(10).toList
Loops have their own scopes. When you replace a loop with a recursive function you are forced to create an explicit scope (the inner method). There is no way around it. This is how it is done. Nothing wrong about it.
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