在 F 中使用 Seq.unfold 的 Seq.cache#

Seq.cache with Seq.unfold in F#

提问人:PineappleDude 提问时间:5/24/2020 更新时间:5/24/2020 访问量:115

问:

我正在尝试缓存无限三角形数字序列的结果。

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

但是,当我尝试缓存时,它似乎没有像我预期的那样工作

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

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

此打印

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

我的缓存是否不正确?打印的第二个序列不应该是第一个序列的延续吗?我不太确定如何进步。

F# 序列 展开

评论

0赞 Asti 5/24/2020
如果是这样的话,就必须变异,这听起来是个坏主意。 将后续枚举与源隔离开来。Seq.taketriNumCcache
0赞 PineappleDude 5/24/2020
@Asti 好吧,我认为这是有道理的。因此,忽略多个 Seq.take,缓存是否正确完成?
1赞 Asti 5/24/2020
是的,第一个 printf 会导致 to evaluate ,但第二个 printf 不会。unfold
1赞 MrD at KookerellaLtd 5/24/2020
默认情况下,表达式是纯的...x 和 y 都等价于同一个表达式,因此您(通常)期望它们是等价的。

答:

1赞 Koenig Lear 5/24/2020 #1

如果你想要继续,你需要跳过。顺序保持不变

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

缓存很好。缓存的好处是,在计算 y 时,从第 5 项开始,因为前 4 项已经缓存。