Scala 编译器不识别尾递归
Scala compiler doesn't recognize tail recursion
我正在尝试使用尾递归创建毕达哥拉斯三重级数,但编译器似乎无法识别它,即使我没有在 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))));
}
}
编辑:根据@AminMal 和@Jörg W Mittag 的评论,确实是 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);
}
}
尾递归方法和局部函数不允许使用return
进行尾递归调用。只需从最后一行删除 return
关键字。
我正在尝试使用尾递归创建毕达哥拉斯三重级数,但编译器似乎无法识别它,即使我没有在 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))));
}
}
编辑:根据@AminMal 和@Jörg W Mittag 的评论,确实是 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);
}
}
尾递归方法和局部函数不允许使用return
进行尾递归调用。只需从最后一行删除 return
关键字。