Переходные коллекции для Scala? - PullRequest
4 голосов
/ 04 апреля 2010

Clojure имеет очень хорошую концепцию переходных коллекций . Есть ли библиотека для Scala (или F #)?

Ответы [ 3 ]

4 голосов
/ 05 апреля 2010

Звучит как отличная концепция для языка, такого как 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 #).

3 голосов
/ 04 апреля 2010

Я не знаю ни одной библиотеки для этого в F # (ничего из стандартной библиотеки, и я не припоминаю, чтобы кто-нибудь видел в блоге что-то подобное, хотя есть ряд библиотек для простых постоянных / неизменных структур). Было бы здорово, если бы кто-то из сторонников создал такую ​​библиотеку. В наши дни Рич Хики - человек, когда дело доходит до этих удивительных практических (в основном -) функциональных структур данных, я люблю читать об этом.

0 голосов
/ 07 апреля 2010

Пожалуйста, взгляните на следующее сообщение Даниэля Спивака:
http://www.codecommit.com/blog/scala/implementing-persistent-vectors-in-scala

Он также перенес алгоритм Рика Хики в Scala. В статье также упоминается IntMap, который почти так же быстр, как реализация Clojure.

...