私が正しく理解していれば、scala.util.control.TailCallsを使用して、トランポリンを使用することにより、非末尾再帰関数のスタックオーバーフローを回避できます。APIで与えられた例は簡単です:
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
ただし、より興味深いケースは、recursve呼び出しの後にいくつかの操作を実行する場合です。私はどういうわけかによって実行されている「ナイーブな」階乗の実装を得ました
def fac(n:Long): TailRec[Long] =
if (n == 0) done(1) else done(n * tailcall(fac(n - 1)).result)
しかし、これはひどいように見え、これが意図された使用法であるとは思えません。だから私の質問は、TailCallsを使用して階乗関数またはフィボナッチ関数を正しく作成する方法です(はい、アキュムレータを使用して末尾再帰を取得する方法を知っています)?または、TailCallsはこの種の問題には適していませんか?