Si entiendo correctamente, scala.util.control.TailCalls se puede usar para evitar desbordamientos de pila para funciones no recursivas de cola mediante el uso de un trampolín. El ejemplo dado en la API es sencillo:¿Cómo utilizar TailCalls?
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
Sin embargo, el caso más interesante es que si quieres hacer algunas operaciones después de la llamada recursve. Tengo una aplicación factorial "ingenua" de alguna manera corriendo por
def fac(n:Long): TailRec[Long] =
if (n == 0) done(1) else done(n * tailcall(fac(n - 1)).result)
pero esto se ve horrible y dudo que esto es el uso previsto. Entonces mi pregunta es cómo escribir correctamente una función factorial o fibonacci usando TailCalls (sí, sé cómo usar los acumuladores para obtener recursivas de cola). ¿O TailCalls no es adecuado para este tipo de problema?
Cuando dices 'scala.util.control.TailCalls es un truco ', ¿podrías decir algo más sobre cuándo es apropiado usarlo? –
"hackear" no fue significado perjorativamente aquí. TailCalls es perfectamente apropiado para evitar el desbordamiento de la pila de llamadas mutuamente recursivas. –