将尾递归转换为非尾递归

时间:2014-01-26 07:04:30

标签: functional-programming

我想知道是否有任何方法可以将尾递归函数转换为非尾递归函数。我知道,尾递归函数比没有尾递归函数更好,如果一个人关注效率,但验证尾递归不合适。

感谢,

1 个答案:

答案 0 :(得分:0)

我怀疑这个问题是否合适,因为尾递归消除是一个优化,如果需要,你可以简单地忽略或关闭以进行验证。 (我想用跳转替换一个调用可能会混淆或损坏某些安全属性。)

但是,如果您确实想要这样做,则需要更改源代码,以便递归函数调用不再处于尾部位置。棘手的部分是确保优化器不会再次更改代码。

考虑这个F#尾递归因子函数:

let rec fact n v =
    if n <= 1
        then v
        else fact (n-1) (n*v)

现在,让我们添加一个根本不执行任何操作的函数,除非将一些全局变量设置为true

// we'll never set this to true, but the compiler doesn't know this
let mutable actuallyDoSomething = false
let doNothing() =
    if actuallyDoSomething then failwith "Don't set actuallyDoSomething!"

现在我们可以在fact中更改尾调用:

let rec fact n v =
    if n <= 1
        then v
        else
            let res = fact (n-1) (n*v)
            doNothing()
            res

类似的技巧应该适用于其他语言。