F#Seq.initInfinite给出StackOverflowException

Tru*_*ill 7 f#

我正在学习F#,而我很难理解为什么会崩溃.这是尝试解决Project Euler问题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
Run Code Online (Sandbox Code Playgroud)

最终版本将调用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一起使用时会爆炸?

SLa*_*aks 14

Seq.initInfinite返回一个以#开头的序列0.

fibonacci当调用零时,您的函数会导致堆栈溢出,因为它永远不会遇到终止情况.

你可以从开始解决这个问题 Seq.initInfinite (fun n -> n + 1)


Bri*_*ian 6

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

(顺便说一句,如果您使用的是Visual Studio调试器,则可以通过检查调用堆栈和本地窗口来轻松诊断.)