Лениво оцениваемый индексированный тип последовательности - PullRequest
9 голосов
/ 25 августа 2011

Мне нужно построить последовательность объектов, которые загружаются из внешнего ресурса.Эта загрузка, являющаяся дорогостоящей операцией, должна быть отложена до тех пор, пока не понадобятся объекты.После того, как коллекция построена, мне нужен индексированный доступ к содержащимся объектам.Предоставляет ли стандартная библиотека Scala коллекцию, подходящую для этого варианта использования?Если нет, то каким будет наилучший способ его реализации?

Редактировать:
Индексированный поиск предпочтительно должен быть операцией O (1).

Ответы [ 3 ]

10 голосов
/ 25 августа 2011

Странно, Майлз недавно написал в Твиттере об этом . Затем ответ указывает на Необходимость в конце Name.scala в скаляре, а другой указывает на спецификации LazyParameter .

Небольшое тестирование с Потребностью:

import scalaz._
import Scalaz._
val longOp = { var x = 0; () => {println("longOp"); x += 1; x }}
val seq = Seq(Need(longOp()), Need(longOp()))
val sum = seq.map(_.value).sum
val sum = seq.map(_.value).sum

val v = Need(longOp())
val s = v.map("got " + _)
println(s.value)
println(s.value)

печать:

longOp: () => Int = <function0>
seq: Seq[scalaz.Name[Int]] = List(
  scalaz.Name$$anon$2@1066d88, scalaz.Name$$anon$2@1011f1f)
longOp
longOp
sum: Int = 3
sum: Int = 3
v: scalaz.Name[Int] = scalaz.Name$$anon$2@133ef6a
s: scalaz.Name[java.lang.String] = scalaz.Name$$anon$2@11696ec
longOp
got 3
got 3

То есть longOp вызывается только один раз при первом доступе к значению.

5 голосов
/ 25 августа 2011

Насколько мне известно, в стандартной библиотеке нет ничего подходящего. Решением может быть использование своего рода Lazy-оболочки для ваших объектов:

class Lazy[A](operation: => A) {
  lazy val get = operation
}

И тогда вы можете создать свой Collection[Lazy[A] с любой коллекцией, которую хотите использовать.

2 голосов
/ 25 августа 2011

Звучит так, как будто вы хотите Поток .

...