4

Clojure 有一个非常好的瞬态集合概念。是否有提供 Scala(或 F#)的库?

4

3 回答 3

4

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

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

使用 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>为接口,所以这只是强制转换)。但是,seq<'a>不保留源集合的属性(例如效率等),您只能使用用于处理序列的通用函数(来自Seq模块)来处理它。但是,我认为这相对接近瞬态集合模式。

类似的 .NET 类型也ReadOnlyCollection<'a>将集合类型(比seq<'a>.

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

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

于 2010-04-04T22:15:17.997 回答
3

我不知道 F# 中有任何用于此的库(标准库中没有,而且我不记得看到任何人写过这样的博客,尽管有许多用于简单持久/不可变结构的库)。某些第三方创建这样的库会很棒。Rich Hickey 是这些天来这些很棒的实用(主要是)功能数据结构的人,我喜欢阅读这些东西。

于 2010-04-04T09:11:40.747 回答
0

Please have a look at the following post by Daniel Spiewak:
http://www.codecommit.com/blog/scala/implementing-persistent-vectors-in-scala

He also ported the algorithm by Rich Hickey to Scala. In the article IntMap is also mentioned which is almost as fast the Clojure implementation.

于 2010-04-07T16:57:22.000 回答