Scala @tailrec带折叠

时间:2015-11-06 12:46:41

标签: scala recursion 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

此代码导致错误:

  

无法优化@tailrec带注释的方法测试:它包含一个   递归调用不在尾部位置

这个问题可以通过模式匹配来解决,但我发现fold看起来更清晰。

1 个答案:

答案 0 :(得分:7)

当你想在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
相关问题