Scala 的瞬态集合?

发布于 2024-08-27 10:30:14 字数 126 浏览 13 评论 0原文

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

Clojure has a very nice concept of transient collections. Is there a library providing those for Scala (or F#)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

三岁铭 2024-09-03 10:30:14

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

I don't know of any library for this in F# (nothing in the standard library, and I don't recall seeing anyone blog anything like this, though there are a number of libraries for simple persistent/immutable structures). It would be great for some third-party to create such a library. Rich Hickey is the man these days when it comes to these awesome practical (mostly-)functional data structures, I love reading about that stuff.

情绪失控 2024-09-03 10:30:14

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

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

使用 seq<'a> type:执行类似操作的一种方法是将数据结构转换为通用序列 (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) (arrays/lists/.. 实现 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> code> 或带有不可变 set<'T>SortedSet<'T>(来自 F# 库)。

This sounds like a really great concept for language like F#, thanks for an interesting link!

When programming with arrays, F# programmers use exactly the same pattern. For example, create a mutable array, initialize it imperatively, return it and then work with it using functions that treat it as immutable such as Array.map (even though the array can actually be mutated as there is no transient array).

Using seq<'a> type: One way to do something similar is to convert the data structure to a generic sequence (seq<'a>) which is an immutable data type and so you cannot (directly) modify the original data structure via seq<'a>. For example:

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

The good thing is that the conversion is usually O(1) (arrays/lists/.. implement seq<'a> as an interface, so this is just cast). However, seq<'a> doesn't preserve properties of the source collection (such as efficiency, etc) and you can process it only using generic functions for working with sequences (from the Seq module). However, I think this is relatively close to the transient collections pattern.

Similar .NET type is also ReadOnlyCollection<'a> which wraps a collection type (somewhat more powerful than seq<'a>) into an immutable wrapper whose operations for modifying collection throw exception.

Related types: For more complicated types of collections, F#/.NET usually have both mutable and immutable implementation (the immutable one coming from F# libraries). The types are usually quite different, but sometimes share a common interface. This makes it possible to use one type when you use mutation and convert it to the other type when you know that you won't need it anymore. However, here you need copy data between different structures, so the conversion definitely isn't O(1). It may be something between O(n) and O(n*log n).

Examples of similar collections are mutable Dictionary<'Key, 'Value> with immutable Map<'Key, 'Value> and mutable HashSet<'T> or SortedSet<'T> with immutable set<'T> (from F# libraries).

末蓝 2024-09-03 10:30:14

请查看 Daniel Spiewak 的以下帖子:
http://www.codecommit.com/blog/scala/实现持久向量in-scala

他还将 Rich Hickey 的算法移植到了 Scala。文章中还提到了 IntMap,它几乎与 Clojure 实现一样快。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文