【问题标题】:Why is this not tail recursive为什么这不是尾递归
【发布时间】:2018-05-04 12:15:49
【问题描述】:

我有一对(共同?)递归函数,它们处理一个元组列表,并根据一些开始和结束条件将它们折叠成批次。

我不怎么做f#,所以我可能很愚蠢。

我已经修改了一个简单的非尾递归版本,通过显式引入构成当前折叠状态的“tot”参数,我认为这是尾递归,但在大输入时我得到了可怕的堆栈溢出....(在调试器和(调试).exe 中)

可能有一种更好的方法可以将其作为显式折叠...但这几乎不是重点,重点是为什么它看起来不是尾递归?

    let rec ignoreUntil2 (xs : List<(string * string)>)  tot = //: List<(string * string)> -> List<List<(string * string)>> -> List<List<(string * string)>> = 
        match xs with              
        | [] -> tot
        | ((s1,s2)::tail) -> 
            if s2.StartsWith("Start importing record: Product") then
                takeUntil2 [] ((s1,s2)::tail) tot
            else
                ignoreUntil2 tail tot
and takeUntil2 acc xs tot = // : List<(string * string)> -> List<(string * string)> -> List<List<(string * string)>> -> List<List<(string * string)>> =
        match xs with
        | [] -> acc :: tot
        | ((s1,s2)::tail)   ->
            let newAcc = ((s1,s2)::acc)
            if s2.StartsWith("Finished importing record: Product") then
                ignoreUntil2 tail (newAcc :: tot)
            else
                takeUntil2 newAcc tail tot

【问题讨论】:

    标签: recursion f# tail-recursion


    【解决方案1】:

    您的代码尾递归的。

    (在调试器和(调试).exe 中)

    默认情况下,F# 编译器不会在调试模式下消除尾调用。您需要显式启用--tailcalls 选项或在发布模式下编译。

    【讨论】:

    • ahchchch这是我生命中的第二次,这已经蜇了我。 span>
    • 我(懒惰地)总是在调试中部署代码(我是一名专业的 c# 程序员),只是因为它使错误变得更好,而且我不能忙于管理调试与生产构建。
    • 让我试试
    • 如何启用它!?!?!你把“--tailcalls”放在隐藏和可怕的地方?
    • 在 Visual Studio 中,可以通过转到 Project -> Properties,选择 Build,然后选中“Generate tail calls”框来启用 D​​ebug 构建。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多