gpt4 book ai didi

scala - 如何制作也可以以非尾递归方式引用自身的尾递归方法

转载 作者:行者123 更新时间:2023-12-01 12:46:30 24 4
gpt4 key购买 nike

假设我有一个长时间运行的计算机制,可以暂停自己稍后恢复:

sealed trait LongRunning[+R];
case class Result[+R](result: R) extends LongRunning[R];
case class Suspend[+R](cont: () => LongRunning[R]) extends LongRunning[R];

运行它们的最简单方法是

@annotation.tailrec
def repeat[R](body: LongRunning[R]): R =
body match {
case Result(r) => r
case Suspend(c) => {
// perhaps do some other processing here
println("Continuing suspended computation");
repeat(c());
}
}

问题是创建这样的计算。假设我们要实现每 10 个周期暂停一次计算的尾递归阶乘:

@annotation.tailrec
def factorial(n: Int, acc: BigInt): LongRunning[BigInt] = {
if (n <= 1)
Result(acc);
else if (n % 10 == 0)
Suspend(() => factorial(n - 1, acc * n))
else
factorial(n - 1, acc * n)
}

但这不编译:

error: could not optimize @tailrec annotated method factorial: it contains a recursive call not in tail position

Suspend(() => factorial(n - 1, acc * n))

如何在非挂起调用上保留尾递归?

最佳答案

我找到了一个可能的答案。我们可以将尾递归部分移动到内部函数中,并在需要时引用外部函数,非尾递归:

def factorial(n: Int, acc: BigInt): LongRunning[BigInt] = {
@annotation.tailrec
def f(n: Int, acc: BigInt): LongRunning[BigInt] =
if (n <= 1)
Result(acc);
else if (n % 10 == 0)
Suspend(() => factorial(n - 1, acc * n))
else
f(n - 1, acc * n)
f(n, acc)
}

关于scala - 如何制作也可以以非尾递归方式引用自身的尾递归方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15334611/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com