You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala编译器无法识别尾递归报Cannot rewrite recursive call解决方案

我尝试通过尾递归生成毕达哥拉斯三元组序列,尽管return语句中没有额外计算逻辑,但编译器无法识别该尾递归,报错Cannot rewrite recursive call: it is not in tail position。

初始编写的尾递归代码

def tailPythagorean(positiveNumber: Int): List[(Int, Int, Int)] = {
  return tailRunner(positiveNumber, positiveNumber, List())
    .take(positiveNumber);
  }

  @tailrec def tailRunner(biggerNumber: Int, smallerNumber: Int, list: List[(Int, Int, Int)]): List[(Int, Int, Int)] = {
    if (biggerNumber == 0 || smallerNumber == 0) {
      return list;
    }

    val smallNumber = if (smallerNumber == 1) biggerNumber - 1 else smallerNumber - 1;
    
    return tailRunner(biggerNumber, smallNumber, List((((biggerNumber + 1) * (biggerNumber + 1) - (smallerNumber * smallerNumber)), (2 * (biggerNumber + 1) * smallerNumber), ((biggerNumber + 1) * (biggerNumber + 1) + (smallerNumber * smallerNumber)))) ::: list);
  }

未做尾递归优化的参考递归实现

def recursivePythagorean(positiveNumber: Int): List[(Int, Int, Int)] = {
  return recursiveRunner(positiveNumber, positiveNumber)
    .take(positiveNumber);
  }

  def recursiveRunner(biggerNumber: Int, smallerNumber: Int): List[(Int, Int, Int)] = {
    if (biggerNumber == 0 || smallerNumber == 0) {
      return List();
    }
    if (smallerNumber == 1) {
      return recursiveRunner(biggerNumber - 1, biggerNumber - 1) ::: List((((biggerNumber + 1) * (biggerNumber + 1) - (smallerNumber * smallerNumber)), (2 * (biggerNumber + 1) * smallerNumber), ((biggerNumber + 1) * (biggerNumber + 1) + (smallerNumber * smallerNumber))));
    }
    else {
      return recursiveRunner(biggerNumber, smallerNumber - 1) ::: List((((biggerNumber + 1) * (biggerNumber + 1) - (smallerNumber * smallerNumber)), (2 * (biggerNumber + 1) * smallerNumber), ((biggerNumber + 1) * (biggerNumber + 1) + (smallerNumber * smallerNumber))));
    }
  }

问题修复

经过验证,问题确实出在return关键字的使用上,移除多余的return关键字后编译器即可正常识别尾递归位置。

修复后的代码

def tailPythagorean(positiveNumber: Int): List[(Int, Int, Int)] = {
    tailRunner(positiveNumber, positiveNumber, List())
      .take(positiveNumber);
  }

  @tailrec def tailRunner(biggerNumber: Int, smallerNumber: Int, list: List[(Int, Int, Int)]): List[(Int, Int, Int)] = {
    if (biggerNumber == 0 || smallerNumber == 0) {
      return list;
    }
    if (smallerNumber == 1) {
      tailRunner(biggerNumber - 1, biggerNumber - 1, List((((biggerNumber + 1) * (biggerNumber + 1) - (smallerNumber * smallerNumber)), (2 * (biggerNumber + 1) * smallerNumber), ((biggerNumber + 1) * (biggerNumber + 1) + (smallerNumber * smallerNumber)))) ::: list);
    }
    else {
      tailRunner(biggerNumber, smallerNumber - 1, List((((biggerNumber + 1) * (biggerNumber + 1) - (smallerNumber * smallerNumber)), (2 * (biggerNumber + 1) * smallerNumber), ((biggerNumber + 1) * (biggerNumber + 1) + (smallerNumber * smallerNumber)))) ::: list);
    }
  }

内容的提问来源于stack exchange,提问作者Echo C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:57:00