Scala @tailrec 折叠
Scala @tailrec with fold
scala 的 @tailrec
注解是否支持 Option.fold
方法?
@tailrec
def test(a: Int): Int =
if (a > 10)
Option(true).fold(test(a - 1))(_ => test(a - 2))
else
-1
此代码导致错误:
Could not optimize @tailrec annotated method test: it contains a
recursive call not in tail position
这个问题可以通过模式匹配来解决,但我发现 fold
看起来干净多了。
当你想在Scala中写一个尾递归函数时,你对尾递归函数的调用需要在最后的位置(因此尾调用递归)。
在你的例子中,Option.fold
是最后一个,Scala 编译器无法确定 fold
的结果总是对 test
.
的调用
您可以使用 TailCals
,使用 fold
编写尾递归函数:
import scala.util.control.TailCalls._
def test(a: Int): TailRec[Int] =
if (a > 10) tailcall(Option(true).fold(test(a - 1))(_ => test(a - 2)))
else done(-1)
test(11).result // -1
如果您发现使用 TailRec
比使用模式匹配更简洁,您可以考虑:
def test(a: Int): Int =
if (a > 10) Option(true) match {
case Some(_) => test(a - 2)
case None => test(a - 1)
}
else -1
scala 的 @tailrec
注解是否支持 Option.fold
方法?
@tailrec
def test(a: Int): Int =
if (a > 10)
Option(true).fold(test(a - 1))(_ => test(a - 2))
else
-1
此代码导致错误:
Could not optimize @tailrec annotated method test: it contains a recursive call not in tail position
这个问题可以通过模式匹配来解决,但我发现 fold
看起来干净多了。
当你想在Scala中写一个尾递归函数时,你对尾递归函数的调用需要在最后的位置(因此尾调用递归)。
在你的例子中,Option.fold
是最后一个,Scala 编译器无法确定 fold
的结果总是对 test
.
您可以使用 TailCals
,使用 fold
编写尾递归函数:
import scala.util.control.TailCalls._
def test(a: Int): TailRec[Int] =
if (a > 10) tailcall(Option(true).fold(test(a - 1))(_ => test(a - 2)))
else done(-1)
test(11).result // -1
如果您发现使用 TailRec
比使用模式匹配更简洁,您可以考虑:
def test(a: Int): Int =
if (a > 10) Option(true) match {
case Some(_) => test(a - 2)
case None => test(a - 1)
}
else -1