2011-11-11 154 views
2

我的代碼(下面)出現堆棧溢出異常。我假設F#不像haskell和dosent和遞歸列表一樣好。在F#中處理像這樣的遞歸列表的正確方法是什麼?我應該通過它一個整數,所以它有一個確定的大小?F#使用遞歸列表

let rec collatz num = 
    match num with 
     |x when x % 2 = 0 ->num :: collatz (x/2)            
     |x ->    num :: collatz ((x * 3) + 1) 

let smallList = collatz(4) |> Seq.take(4) 
+4

除了丹尼爾的答案 - 這個問題是不是事實,名單是_recursive_ - 這是在F#完美的罰款。問題在於列表是_infinite_,F#列表默認情況下不是懶惰的。 –

回答

5

對於像這樣的無限列表,您想要返回一個序列。序列是懶惰的;列表不是。

let rec collatz num = 
    seq { 
    yield num 
    match num with 
    | x when x % 2 = 0 -> yield! collatz (x/2)            
    | x -> yield! collatz ((x * 3) + 1) 
    } 

let smallList = 
    collatz 4 
    |> Seq.take 4 
    |> Seq.toList //[4; 2; 1; 4] 
0
let collatz num = 
    let next x = if x % 2 = 0 then x/2 else x * 3 + 1 
    (num, next num) 
    |>Seq.unfold (fun (n, x) -> Some (n, (x, next x)))