scala - Scala 的 transient 集合?

标签 scala f# functional-programming scala-collections transient

Clojure 有一个非常好的概念 transient collections .是否有提供 Scala(或 F#)的库?

最佳答案

对于像 F# 这样的语言来说,这听起来是一个非常棒的概念,感谢您提供有趣的链接!

使用数组进行编程时,F# 程序员使用完全相同的模式。例如,创建一个可变数组,命令式地初始化它,返回它,然后使用将它视为不可变的函数来处理它,例如 Array.map (即使数组实际上可以突变,因为没有 transient 数组)。

使用 seq<'a> 类型:做类似事情的一种方法是将数据结构转换为通用序列( seq<'a> ),它是一种不可变的数据类型,因此您不能(直接)通过 seq<'a> 修改原始数据结构.例如:

let test () = 
  let arr = Array.create 10 0
  for i in 0 .. (arr.Length - 1) do
    arr.[i] <- // some calculation
  Array.toSeq arr

好消息是转换通常是 O(1)(数组/列表/.. 实现 seq<'a> 作为接口(interface),所以这只是强制转换)。但是,seq<'a>不保留源集合的属性(例如效率等),您只能使用处理序列的通用函数(来自 Seq 模块)来处理它。但是,我认为这相对接近 transient 集合模式。

类似的.NET类型也是ReadOnlyCollection<'a>它将集合类型(比 seq<'a> 更强大)包装到一个不可变的包装器中,该包装器用于修改集合的操作抛出异常。

相关类型:对于更复杂的集合类型,F#/.NET 通常同时具有可变和不可变实现(来自 F# 库的不可变实现)。这些类型通常完全不同,但有时共享一个通用接口(interface)。这使得在您使用突变时可以使用一种类型,并在您知道不再需要它时将其转换为另一种类型。但是,这里您需要在不同结构之间复制数据,因此转换绝对不是 O(1)。它可能介于 O(n) 和 O(n*log n) 之间。

类似集合的示例是可变的 Dictionary<'Key, 'Value>不可变 Map<'Key, 'Value>和可变的HashSet<'T>SortedSet<'T>不可变 set<'T> (来自 F# 库)。

关于scala - Scala 的 transient 集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2573966/

相关文章:

scala - 揭穿 Scala 神话

scala - Scala 方法 def 什么时候应该使用显式定义的返回类型?

f# - 等效于 F# 中的 C# async main

.net - WPF 的 F# 异步事件处理程序类似于 C# 的 async 和 await

java - 有没有好的 Clojure 基准?

scala - 将其他列表转换为 HList 中的任一个

scala - 在集群节点上运行的 Akka Streams

f# - 为什么这个内联元组不起作用?

scala - 以函数式方式计算文法的可空非终结符(最好在 Scala 中)

java - 为什么不能所有 Functor 都是 Monad?