2011-08-25 12 views
9

Necesito construir una secuencia de objetos que se cargan desde un recurso externo. Esta carga, que es una operación costosa, debe retrasarse hasta el momento en que se necesiten los objetos. Después de compilar la colección, necesito un acceso indexado a los objetos contenidos. ¿La biblioteca estándar de Scala proporciona una colección adecuada para este caso de uso? Si no, ¿cuál será la mejor manera de implementarlo?Lazly evaluó secuencia indexada tipo

Editar:
La búsqueda indexada debe ser preferiblemente un (1) operación O.

Respuesta

9

Extraño, Miles recientemente tweeted about this. A continuación, una respuesta señala Needal final de Name.scala en scalaz y otra apunta a las especificaciones 'LazyParameter.

pocas pruebas con Need:

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) 

impresiones:

longOp:() => Int = <function0> 
seq: Seq[scalaz.Name[Int]] = List(
    [email protected], [email protected]) 
longOp 
longOp 
sum: Int = 3 
sum: Int = 3 
v: scalaz.Name[Int] = [email protected] 
s: scalaz.Name[java.lang.String] = [email protected] 
longOp 
got 3 
got 3 

Así longOp sólo se le llama una vez en el primer acceso de valor.

+0

Muchas gracias, no pude recordarme dónde lo he visto antes. – Nicolas

+0

'Nombre' parece estar evaluando' valor' en cada acceso: http://paste.pocoo.org/show/464187/. Eso es indeseable. – missingfaktor

+1

@missingfaktor, sí, use * Need * hidden al final del archivo. – huynhjl

2

Parece que quiere un Stream.

+0

La transmisión es una lista diferida, y el acceso indexado en una secuencia es una operación 'O (n)'. Quiero algo con características de rendimiento 'O (1)' para la búsqueda basada en índices. – missingfaktor

+1

debe agregar esta consideración de rendimiento a su pregunta. Es un elemento importante. – Nicolas

+0

@Nicolas: agregado. Gracias. – missingfaktor

5

Que yo sepa, no hay nada que encaje en la biblioteca estándar. Una solución podría ser utilizar una especie de perezoso envoltorio para sus objetos:

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

Y entonces usted puede construir su Collection[Lazy[A] con cualquier tipo de colección que desea utilizar.

+0

+1, eso es exactamente lo que actualmente tengo resuelto. (Excepto que mi 'get' es' unary_! ':-) Pensé que podría haber una mejor alternativa, ya sea en algunos rincones escondidos de stdlib o en Scalaz. – missingfaktor

+0

Puede ser algo en scalaz, no estoy familiarizado con él. – Nicolas

Cuestiones relacionadas