당신은 할 수 있지만,이 게으르게 평가하지 않습니다 예를 들어
def bin(s: String, n: Int): Stream[String] = {
if (s.length == n) {
println("got " + s) // for figuring out when it's evaluated
Stream(s)
} else {
val s0 = s + '0'
val s1 = s + '1'
bin(s0, n) ++ bin(s1, n)
}
}
, bin("", 2).take(2).foreach(println)
을 실행하면 다음과 같은 출력을 얻을 것이다 :
scala> bin("", 2).take(2).foreach(println)
got 00
got 01
got 10
got 11
00
01
당신이 괜찮다면 TraversableView
을 사용하면 https://stackoverflow.com/a/3816012/257449에 설명 된 변환을 사용할 수 있습니다. 그럼 코드가된다 : 다음
def toTraversable[T](func : (T => Unit) => Unit) = new Traversable[T] {
def foreach[X](f : T => X) = func(f(_) : Unit)
}
def bin2(str: String, n: Int) = {
def recurse[U](s: String, f: (String) => U) {
if (s.length == n) {
println("got " + s) // for figuring out when it's evaluated
f(s)
} else {
recurse(s + '0', f)
recurse(s + '1', f)
}
}
toTraversable[String](recurse(str, _)) view
}
scala> bin2("", 2).take(2).foreach(println)
got 00
00
got 01
01
got 10
고마워, 정확히 내가 뭘 찾고있어 :) 그것은 원래의 backtracking 버전보다 더 효율적으로 (스택 메모리 소비면에서) 보이지 않습니까? – Michael
@Michael 아마도. 나는'Stream'을 사용하는 코드의 분석 효율이 좋지 않습니다. 사용하는 것이 필요한 경우 REPL에서 코드가 오버플로되지 않았는지 테스트해야합니다. –
@Michael, 스트림 버전은 스택 프레임 사용면에서 효율성이 떨어집니다. 각각의 재귀 호출은 4 개의 스택 프레임을 사용합니다. 실제로는이 예제에서는 문제가되지 않습니다. 힙 메모리 사용과 관련하여 Stream 클래스는 저장된 참조 당 메모리 사용량 중 스칼라 콜렉션 중 가장 효율적이지 않지만 일반적으로 스트림의 헤드를 우연히 들지 않으면 대개 괜찮습니다 ... – huynhjl