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 API is straightforward:
import scala.util.control.TailCalls._
def isEven(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(true) else tailcall(isOdd(xs.tail))
def isOdd(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(false) else tailcall(isEven(xs.tail))
isEven((1 to 100000).toList).result
However, the more interesting case is if you want to do some operations after the recursve call. I got a "naive" factorial implementation somehow running by
def fac(n:Long): TailRec[Long] =
if (n == 0) done(1) else done(n * tailcall(fac(n - 1)).result)
but this looks horrible and I doubt that this is the intended use. 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)? Or is TailCalls not suitable for this kind of problem?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…