【问题标题】:Scala: Why this function is not tail recursive?Scala:为什么这个函数不是尾递归的?
【发布时间】:2016-12-27 18:31:04
【问题描述】:

我有这样的合并排序实现:

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 函数中的递归调用不在尾部位置。 但它处于尾部位置。没有蹦床有什么办法可以解决吗?

【问题讨论】:

    标签: scala recursion functional-programming tail-recursion purely-functional


    【解决方案1】:

    原因在于step 是一个返回签名函数的函数:Seq[Seq[T]] =&gt; Seq[T]。所以递归调用不是直接调用同一个方法,而是先获取这个函数,然后给定参数调用,不是尾递归。

    要解决这个错误,你必须这样声明step

    @tailrec
    def step(seq: Seq[Seq[T]]): Seq[T] = seq match {
      ...
    }
    

    【讨论】:

      猜你喜欢
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多