F#Seq.initInfinite给出StackOverflowException

时间:2010-05-11 02:08:11

标签: f#

我正在学习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

最终版本会调用sum函数(并且会有超过55的限制),但这是学习代码。

原样,这会产生StackOverflowException。但是,如果我在[1..30]中发表评论并注释掉Seq.initInfinite,我会得到:

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中所期望的那样,它似乎按需生成项目。那么为什么在与initInfinite一起使用时会爆炸?

2 个答案:

答案 0 :(得分:14)

Seq.initInfinite返回从0开始的序列。

当使用零调用时,fibonacci函数会导致堆栈溢出,因为它永远不会遇到终止案例。

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

开始解决此问题

答案 1 :(得分:6)

你从0开始用initInfinite,然后递归-1,-2,......

(顺便说一下,如果您使用的是Visual Studio调试器,通过检查调用堆栈和本地窗口,可以很容易地进行诊断。)