Avrohom Yisroel
Avrohom Yisroel

Reputation: 9492

Why can't I Seq.take more than 5 values?

Whilst trying to understand Seq.unfold, I have been playing with the following F# that produces a sequence of the triangle numbers...

let tri_seq = 
  1.0 
  |> Seq.unfold (fun x -> Some (0.5 * x * (x + 1.0), x + 1.0)) 
  |> Seq.map (fun n -> int n)

This seems to work fine, in that I can do the following...

tri_seq |> Seq.nth 10

...and it shows the right number, whatever value I pass to it.

Now, I'm trying to print out the first (say) ten values in the sequence, rather that the above code which only gets the nth. I tried the following...

tri_seq |> Seq.take 10 |> Seq.map (fun n -> printfn "%d" n)

...but that only prints the first five values. Whatever I use for the value passed to Seq.take, I only ever get a maximum of five results, even though when using Seq.nth, I can go as far as I like.

Anyone able to explain this to me? Why can't I get past the fifth value?

Upvotes: 2

Views: 127

Answers (1)

Tomas Petricek
Tomas Petricek

Reputation: 243096

The problem is that you're using Seq.map to print the values. Sequences are lazy and the resulting sequence is never evaluated - you see 5 values probably because F# Interactive prints the first five elements of the sequence.

You can use Seq.iter which iterates over the whole sequence:

tri_seq |> Seq.take 10 |> Seq.iter (fun n -> printfn "%d" n)

The key difference is that Seq.map returns a new sequence with the values produced by the function you specify while Seq.iter does not return anything and just iterates over the input.

In this case, you can actually use partial function application and make the code a bit shorter:

tri_seq |> Seq.take 10 |> Seq.iter (printfn "%d")

Upvotes: 6

Related Questions