seq { for i in 1 .. 10 do yield i * i }-6ren">
gpt4 book ai didi

F#:如何评估 "seq"来急切地获取其所有值?

转载 作者:行者123 更新时间:2023-12-04 09:05:05 27 4
gpt4 key购买 nike

我们知道在F#中,seq是惰性计算的。我的问题是,如果我的seq值数量有限,如何将其转换为包含所有求值值的数据类型?

> seq { for i in 1 .. 10 do yield i * i };;
val it : seq<int> = seq [1; 4; 9; 16; ...]

非常感谢。

最佳答案

@Carsten的答案是正确的:如果您希望将懒惰求值的序列转换为列表或数组,则可以使用Seq.toArraySeq.toList。但是,不要使用这些功能来强制评估。

人们通常会问这个问题的最常见原因是因为他们的预测涉及副作用,因此他们希望进行评估。以这个示例为例,其中希望将值打印到控制台:

let lazySeq = seq { for i in 1 .. 10 do yield i * i }
let nothingHappens = lazySeq |> Seq.map (printfn "%i")

问题在于,当您评估这两个表达式时, 不会发生任何事情:
> 

val lazySeq : seq<int>
val nothingHappens : seq<unit>

因为 nothingHappens是一个延迟评估的序列,所以 map不会产生任何副作用。

人们经常诉诸 Seq.toListSeq.toArray来强制评估:
> nothingHappens |> Seq.toList;;
1
4
9
16
25
36
49
64
81
100
val it : unit list =
[null; null; null; null; null; null; null; null; null; null]

尽管这种方法有效,但它并不是特别习惯用的方法。它产生一个奇怪的返回类型: unit list

更加惯用的解决方案是使用 Seq.iter:
> lazySeq |> Seq.iter (printfn "%i");;
1
4
9
16
25
36
49
64
81
100
val it : unit = ()

如您所见,这将强制执行评估,但返回类型更为合理 unit

关于F#:如何评估 "seq"来急切地获取其所有值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35169269/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com