2011-08-25 2 views
9

외부 리소스에서로드 된 일련의 개체를 작성해야합니다. 이로드는 값 비싼 작업이므로 오브젝트가 필요할 때까지 지연시켜야합니다. 콜렉션이 빌드 된 후에는 포함 된 오브젝트에 대한 색인 액세스가 필요합니다. 스칼라 표준 라이브러리는이 유스 케이스에 적합한 컬렉션을 제공합니까? 그렇지 않다면, 그것을 구현하는 가장 좋은 방법은 무엇입니까?느리게 평가 된 인덱스 된 시퀀스 유형

편집 :
색인 된 룩업은 O (1) 조작이 바람직합니다.

답변

9

Strange, Miles 최근에 tweeted about this. 회신은 scalaz의 Name.scala 끝에의 Need으로 지적하고 또 하나는 specs '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(
    [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 

그래서 longOp는 값의 첫 번째 액세스에 한 번이라고합니다.

+0

고마워, 내가 전에 본 곳을 생각 나게 할 수 없었다. – Nicolas

+0

'Name'은 각 액세스에서 'value'를 평가하는 것 같습니다 : http://paste.pocoo.org/show/464187/. 그것은 바람직하지 않습니다. – missingfaktor

+1

@missingfaktor, yes - 파일 끝 부분에 * Need * hidden을 사용하십시오. – huynhjl

2

Stream처럼 들릴 수도 있습니다.

+0

스트림은 지연 목록이며 스트림에서 인덱싱 된 액세스는 'O (n)'작업입니다. 나는 색인 기반 룩업을 위해'O (1)'성능 특성을 가진 것을 원한다. – missingfaktor

+1

질문에이 성능 고려 사항을 추가해야합니다. 중요한 요소입니다. – Nicolas

+0

@Nicolas : 추가됨. 감사. – missingfaktor

5

제가 아는 바로는 표준 라이브러리에는 적합하지 않습니다. 해결책은 개체에 대한 게으른 래퍼의 종류를 사용할 수 있습니다 :

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

을 그리고 당신은 당신이 사용하고자하는 수집의 종류와 Collection[Lazy[A]을 구축 할 수 있습니다.

+0

+1, 그게 바로 제가 현재 정착 한 것입니다. (제'get은'unary_! '입니다 :-) 나는 stdlib이나 Scalaz의 일부 숨겨진 모서리에서 더 나은 대안이있을 것이라고 생각했습니다. – missingfaktor

+0

스 카즈에서 일부 일지 모르지만 익숙하지 않습니다. – Nicolas

관련 문제