1

I'm trying to cache the result of an infinite sequence of triangle numbers.

let triCalc n = (n*(n+1))/2
let triNumC = 0 |> Seq.unfold (fun n -> Some((triCalc n, n+1))) |> Seq.cache

However, when I try to cache it doesn't seem to work as I expect

let x = Seq.take 4 (triNumC)
let y = Seq.take 4 (triNumC)

printf "%A" x
printf "%A" y

This prints

seq [0; 1; 3; 6]seq [0; 1; 3; 6]

Am I caching incorrectly? Shouldn't the second sequence printed be a continuation of the first? I am not quite sure how to progress.

  • If that were the case, `Seq.take` would have to mutate `triNumC`, which sounds like a bad idea. `cache` isolates subsequent enumerations from the source. – Asti May 24 '20 at 14:04
  • @Asti Okay, I think that makes sense. So disregarding the multiple Seq.take, is the cache done correctly? – PineappleDude May 24 '20 at 14:10
  • 1
    Yes, the first printf would cause the `unfold` to evaluate, but the second printf wouldn't. – Asti May 24 '20 at 14:12
  • 1
    by default the expressions are pure...both x and y are equivalent to the same expression, so you would (normally) expect them to be equivalient. – MrD at KookerellaLtd May 24 '20 at 15:47

1 Answers1

1

If you want the continuation you need to skip. The sequence remains the same

let y = triNumC
        |> Seq.skip 4
        |> Seq.take 4

Caching is fine. The benefit of caching is that when calculating y is that starts from the 5th term onwards since the first 4 are already cached.

Koenig Lear
  • 2,366
  • 1
  • 14
  • 29