2011-11-11 15 views
2

私のコード(以下)は、スタックオーバーフローの例外を伴います。 ImはF#がhaskellのようなものではないと仮定しています。 F#のような再帰的リストを扱う正しい方法は何ですか?私はintそれを渡す必要がありますので、それは決まったサイズを持っていますか?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))) 
関連する問題