Y组合器是有用的,但我认为你真的想要尾递归优化,它消除了使用堆栈的尾递归函数。只有当每次递归调用的结果立即由调用者返回并且在调用之后从不进行任何额外的计算时,才能实现尾递归。不幸的是C#不支持尾递归优化,但是你可以用蹦床来模拟它,它允许从尾递归方法到蹦床包装方法的简单转换。
// Tail
int factorial(int n) { return factorialTail(n, 1, 1); }
int factorialTail(int n, int i, int acc) {
if (n < i) return acc;
else return factorialTail(n, i + 1, acc * i);
}
// Trampoline
int factorialTramp(int n) {
var bounce = new Tuple<bool,int,int>(true,1,1);
while(bounce.Item1) bounce = factorialOline(n, bounce.Item2, bounce.Item3);
return bounce.Item3;
}
Tuple<bool,int,int> factorialOline(int n, int i, int acc) {
if (n < i) return new Tuple<bool,int,int>(false,i,acc);
else return new Tuple<bool,int,int>(true,i + 1,acc * i);
}
不幸的是,不,我正在使用C#,并且跨越3个独立的集合进行循环,每个集合生成2到3个内部集合,需要调用多达8个不同版本的同一个函数,在他们之间变化。我设法将它重写为一个函数(仍然接近120行),它会递归地调用它自己,但不会使用尾递归,因此它会在第900次调用时爆炸。 –
据我了解,C#支持.NET 4.0以来的适当尾递归:[.NET Framework 4中的尾调用改进](http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/tail -call-improvements-in-net-framework-4.aspx)和[C#和F#中的尾递归](http://lookingsharp.wordpress.com/2010/03/08/tail-recursion-in-csharp-and -fsharp /)。当编译任何CPU并在64位机器上运行程序时,它肯定会进行尾递归优化 - 如果这有帮助... –
@SaschaHennig:很高兴知道,谢谢。 –