代码之家  ›  专栏  ›  技术社区  ›  TrueWill

f seq.initfinite给出stackOverflowException

f#
  •  7
  • TrueWill  · 技术社区  · 14 年前

    我正在学习f,我很难理解为什么会崩溃。这是一种解决问题的尝试 Project Euler problem 2 .

    let rec fibonacci n =
        if n = 1 then
            1
        elif n = 2 then
            2
        else
            fibonacci (n - 1) + fibonacci (n - 2)
    
    let debugfibonacci n =
        printfn "CALC: %d" n
        fibonacci n
    
    let isEven n =
        n % 2 = 0
    
    let isUnderLimit n =
        n < 55
    
    let getSequence =
        //[1..30]
        Seq.initInfinite (fun n -> n)
        |> Seq.map debugfibonacci
        |> Seq.filter isEven
        |> Seq.takeWhile isUnderLimit
    
    Seq.iter (fun x -> printfn "%d" x) getSequence
    

    最终版本将调用一个求和函数(并且将有一个高于55的上限),但这是学习代码。

    同样,这会给出stackOverflowException。但是,如果我在[1..30]中注释并注释seq.initfinite,我得到:

    CALC: 1
    CALC: 2
    2
    CALC: 3
    CALC: 4
    CALC: 5
    8
    CALC: 6
    CALC: 7
    CALC: 8
    34
    CALC: 9
    CALC: 10
    CALC: 11

    它似乎是按需生成项目,正如我在Linq中所期望的那样。那么,为什么它与initfinite一起使用时会爆炸呢?

    2 回复  |  直到 14 年前
        1
  •  14
  •   SLaks    14 年前

    Seq.initInfinite 返回开始于的序列 0 .

    你的 fibonacci 函数在用零调用时会导致堆栈溢出,因为它从不命中终止事例。

    你可以从 Seq.initInfinite (fun n -> n + 1)

        2
  •  6
  •   Brian    14 年前

    从0开始 initInfinite ,然后重复-1,-2,…

    (顺便说一句,如果您使用的是Visual Studio调试器,那么通过检查调用堆栈和局部变量窗口,这很容易诊断。)