Seq.cache
кэширует экземпляр IEnumerable<T>
, так что каждый элемент в последовательности вычисляется только один раз. Однако в вашем случае вы кэшируете последовательность, возвращаемую функцией, и каждый раз, когда вы вызываете функцию, вы получаете новую кэшированную последовательность, которая не приносит вам никакой пользы. Я не думаю, что кэширование - это действительно правильный подход к вашей проблеме, как вы обрисовали ее; Вместо этого вам, вероятно, стоит заняться запоминанием.
Если вместо определения функции, дающей простые числа, меньшие n
, вы хотите определить бесконечную перечисляемую последовательность простых чисел, то кэширование имеет больше смысла. Это было бы больше похоже на это:
let rec upFrom i =
seq {
yield i
yield! upFrom (i+1)
}
let rec primes =
seq {
yield 2
yield!
upFrom 3 |>
Seq.filter (fun p -> primes |> Seq.takeWhile (fun j -> j*j <= p) |> Seq.forall (fun j -> p % j <> 0))
}
|> Seq.cache
Я не сравнивал эффективность этого метода с вашими.