为什么scala编译器没有标记看似不是尾递归函数的东西?

时间:2016-02-15 18:20:22

标签: scala tail-recursion

我已经标记了方法sameLength来检查和优化尾递归。我觉得sameLength方法中的最后一个操作不是同一个Length。它是&&。和&&在else子句中。为什么编译器不会标记这个。由于编译器没有标记它,我认为它确实是尾递归的。有人可以为我定义尾递归吗?我脑子里的定义错了。

  import scala.annotation.tailrec


  object TestTailRec extends App{

    @tailrec
    def sameLength[T](xs: List[T], ys: List[T]) : Boolean = {
      if(xs.isEmpty) ys.isEmpty
      else ys.nonEmpty && sameLength(xs.tail, ys.tail)
    }

    println(sameLength(List(1,2,3), List(1,2,3)))

  }

2 个答案:

答案 0 :(得分:2)

The spec定义了&&的{​​{1}}方法。

由于Boolean是一个值类,因此Boolean表达式是内联的。

由于if/else参数是按名称,因此不会先评估它。

严格的版本证实了你的直觉:

p

答案 1 :(得分:0)

让我们稍微重构你的方法,而不改变它的含义:

def sameLength[T](xs: List[T], ys: List[T]) : Boolean = {
  if(xs.isEmpty) ys.isEmpty
  else if (ys.isEmpty) false else
  sameLength(xs.tail, ys.tail)
}

我认为现在很明显这是尾递归