2011-11-11 2 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

은 - 즉 F 번호에 완벽하게 괜찮아요 - 문제는 목록 _recursive_ 사실이 아니다. 문제는 목록이 _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)))