If I understand correctly, scala.util.control.TailCalls can be used to avoid stack overflows for non-tail-recursive functions by using a trampoline. The example given in the
This question is more than 6 years old, but the accepted answer doesn't seem to answer the question:
So my question is how to write a factorial or fibonacci function correctly using TailCalls (yes, I know how to use accumulators to get them tail-recursive)?
So, here it is:
object Factorial {
/**
* Returns the nth factorial
*/
def apply(n: Long): BigInt = {
if (n < 0)
throw new IllegalArgumentException("Can't factorial to an index less than 0")
else {
import scala.util.control.TailCalls._
def step(current: Long): TailRec[BigInt] = {
if (current <= 0)
done(1)
else
tailcall {
for {
next <- step(current - 1)
} yield current * next
}
}
step(n).result
}
}
}
assert(Factorial(0) == 1)
assert(Factorial(7) == 5040)
assert(Factorial(10) == 3628800)
One of the big use-cases for using TailCalls is to do something that is right-fold-like.