Question
Is there a simpler Seq.unfold
version that just takes the previous element as the state? I know you can easily adapt Seq.unfold
to do that, but the result is not very readable.
Solution
I don't think there is a built-in function that does that.
Repeating the same pattern using Seq.unfold
would be quite annoying, but you can easily use unfold
to define a function that behaves as you want and then just use the new function:
module Seq =
let generate f v =
Seq.unfold (fun v -> let r = f v in Some(r, r)) v
As an aside, if I wanted to implement the pattern, I would probably go with a simple recursive sequence expression, which might be easier to read than using Seq.unfold
. The generate
function can be implemented like this:
let rec generate f v = seq {
yield v
yield! generate f (f v) }
This behaves a bit differently, because it yields the first value as well. Not sure what behaviour you want.
OTHER TIPS
Tomas' answer is good but, like you said, using Seq.unfold
to do this is ugly, and, as he said, his generate
function behaves differently.
If you want the same behavior as Seq.unfold
, but using the previous element as state, this should do it:
let rec unfold f state =
seq {
match f state with
| Some x ->
yield x
yield! unfold f x
| None -> ()
}