The key problem with the sample is that you're using Seq.initInfinite
instead of Seq.unfold
.
Seq.initInfinite
calls the specified function with the index of the element as argument (0, 1, 2, ..)Seq.unfold
calls the specified function with the state generated by the previous iteration
Note that your code also does not use the argument x
and so your function ends up being 'a -> int
rather than int -> int
which is what you'd expect - this is a good indication that there is something wrong!
To fix this, try something like this:
let conjv2 x =
let next n = match n%2 with
|0 -> n/2
|_ -> n*3+1
Seq.unfold (fun st -> let n = next st in Some(n, n)) x
|> Seq.takeWhile(fun n -> n > 1)
|> Seq.map (fun v -> printfn "%A" v; v)
|> Seq.length
The function passed to unfold
needs to return an option with the new state & a value to emit. To generate infinite sequence, we always return Some
and the emitted values are the intermediate states.
This returns values that are smaller by 2 than your original conj
, because conj
starts with 1 (rather than 0) and it also counts the last value (while here, we stop before ansa=1
). So you'll need to add 2 to the result.