在调试记忆函数时,我发现自己试图找出Seq.mapi
是否真的在迭代序列,所以我用如下所示的printfn
调用替换了一个匿名函数:
let x = "test" |> Seq.map (fun c -> c |> printfn "%c")
令我惊讶的是,打印到控制台的副作用从未发生过,在 FSI 中它只是返回val d : seq<unit>
.虽然这个结果是正确的,但我原本预计当map
函数迭代序列时,副作用会开始。即,当我用Seq.map id
替换它时,它会按预期工作并自行返回。
当我用Seq.iter
或Seq.iteri
替换Seq.map
或Seq.mapi
时,它实际上确实打印了副作用。
现在我认为这是由于序列被延迟计算,并且 F# 在内部要么创建一个闭包序列,要么在它被调用之前实际上什么都不做,因为如果我Seq.last d
,它确实会打印序列中的所有项目。
F# 中的seq
是IEnumerable
的别名,因此Seq
模块函数大多等效于 Linq。是的,他们被懒惰地评估。