偶尔,我想从函数中返回一个可变集合作为序列。上传到seq<_>
有效,但序列可以被下调和修改(通常不重要)。我通常的解决方案是使用wrap-as-a-sequence函数,它产生了以下结果:
let wrap items = Seq.map id
let wrapDict dict = Seq.map ((|KeyValue|) >> snd)
主要是出于好奇(和乐趣),编写这些函数的其他方式是什么,可能是以更惯用,更简洁或更有效的方式?
答案 0 :(得分:5)
Seq.readonly是您正在寻找的功能。
答案 1 :(得分:2)
我认为Stephan建议的功能可能就是你要找的东西。
然而,有一件棘手的事情 - Seq.readonly
函数(以及ReadOnlyCollection
或使用Seq.map
)包装序列,以便它不能从外部变异。但是,它仍然具有非常微妙的行为,因为结果序列可以被对象突变:
type Arr() =
let data = [| 1 .. 5 |]
member x.ItemsSeq = Seq.readonly data
member x.Mutate() = data.[0] <- 10
let a = Arr()
let s = a.ItemsSeq
printfn "%A" (s |> List.ofSeq) // [1; 2; 3; 4; 5]
a.Mutate()
printfn "%A" (s |> List.ofSeq) // [10; 2; 3; 4; 5]
我认为这是一种非常意外的行为(在一种主要是功能性的语言中)。
因此,如果内部集合是可变的,您还可以考虑创建一个以后无法修改的数据的完整克隆,并保证返回的序列始终提供相同的结果。例如,使用data |> Array.ofSeq |> Seq.readonly