我正在学习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一起使用时会爆炸?
答案 0 :(得分:14)
Seq.initInfinite
返回从0
开始的序列。
当使用零调用时,fibonacci
函数会导致堆栈溢出,因为它永远不会遇到终止案例。
您可以从Seq.initInfinite (fun n -> n + 1)
答案 1 :(得分:6)
你从0开始用initInfinite
,然后递归-1,-2,......
(顺便说一下,如果您使用的是Visual Studio调试器,通过检查调用堆栈和本地窗口,可以很容易地进行诊断。)