我有Merge Sort的实现:
import scala.annotation.tailrec
object MergeSort {
def sortBy[T]: ((T, T) => Int) => Seq[T] => Seq[T] = comparator => seqToSort => {
@tailrec
def merge(xs : Seq[T], ys : Seq[T], accum : Seq[T] = Seq()) : Seq[T] = (xs, ys) match {
case (Seq(), _) => ys ++ accum
case (_, Seq()) => xs ++ accum
case (x::rx, y::ry) =>
if(comparator(x, y) < 0)
merge(xs, ry, y +: accum)
else
merge(rx, ys, x +: accum)
}
@tailrec
// Problem with this function
def step : Seq[Seq[T]] => Seq[T] = {
case Seq(xs) => xs
case xss =>
val afterStep = xss.grouped(2).map({
case Seq(xs) => xs
case Seq(xs, ys) => merge(xs, ys)
}).toSeq
// Error here
step(afterStep)
}
step(seqToSort.map(Seq(_)))
}
}
它无法编译。它表示 step 函数中的递归调用不在尾部位置。 但它处于尾部位置。有没有办法在没有蹦床的情况下解决它?
答案 0 :(得分:6)
原因是step
是一个返回签名函数的函数:Seq[Seq[T]] => Seq[T]
。因此递归调用不会直接调用相同的方法,而是首先获取此函数,然后为给定的参数调用它,这不是尾递归。
要解决此错误,您必须以这种方式声明step
:
@tailrec
def step(seq: Seq[Seq[T]]): Seq[T] = seq match {
...
}