2011-03-11 3 views
6

내가 스칼라에서 피보나치 nums의 정확하고 유용한 정의가 될 것이라고 생각 것입니다 다음과 같은 오류가 발생합니다 :Scalas (A, B) .zip입니다 (또는 Tuple2.zipped) 개념을 사용하여 스트림/무한리스트

fibs take 10 foreach println 
0 
1 
java.lang.StackOverflowError 
    at scala.collection.mutable.LazyBuilder.(LazyBuilder.scala:25) 
    at scala.collection.immutable.Stream$StreamBuilder.(Stream.scala:492) 
    at scala.collection.immutable.Stream$.newBuilder(Stream.scala:483) 
    at... 

나는 스트림이 제대로 작동하지 않을 것 같습니까? 이 작업을 수행하는 방법에 대한 제안 사항 또는이 작업이 수행되지 않는 이유 (작동하지 않아야 함)는 무엇입니까?

+0

저는이 _exact_ 질문을하기로했습니다. 나보다 먼저 여기있는 누군가를 알게 돼. +1 – KChaloux

답변

8

다음 작품이 제대로

val fibs:Stream[Int] = 0 #:: 1 #:: (fibs zip fibs.tail).map{ case (a,b) => a+b } 

Tuple2.zipped의 문제는 그것이 압축하는 것 시퀀스에 foreach을 실행할 수있는 가정이다. 이것은 아마도 설계 상으로는 Stream.zip이 구현하는 방식을 수행하면 또는 Stream이 아닌 임의의 유한 길이 Seq에 대해 나쁜 성능을 제공 할 수 있습니다. (가장 데이터 구조가 tail의 효율적인 구현을 지원하지 않기 때문에.)


Stream.zip는 기본적으로 (이 유형은 일반적인하기 위해 몇 가지 물건을 수행하지만) 다음과 같이 구현됩니다. 스칼라의 Trac의 데이터베이스에서이에 티켓이있다

class Stream[A]{ 
    def zip(other:Stream[B]) = 
    (this.head, other.head) #:: (this.tail zip other.tail) 
} 
+0

귀하의 질문에'게으른'한정어는 불필요했지만, 내 대답에서 그것을 제거하는 것은이 일을하게 만든 것이 아니 었음을 확신합니다. –

+0

좋아, 당신이 보여준 것은 아주 멋지다. 나는 이것이 단지 haspell과 같은 인자로 2-arity 함수를 취하는 "zipWith"가 얼마나 필요한지를 보여줄 것이라고 생각한다. 스칼라에 왜 존재하지 않는지 모르겠다. – Felix

+1

@Felix :'zipWith'가 어떻게 도움이되는지 모르겠습니다. 튜플에있는'zipWith'는 여전히 첫 번째리스트가 무한한 스트림이었을 때 오버 플로우되는'foreach'로 구현 될 것입니다. –

3

: http://lampsvn.epfl.ch/trac/scala/ticket/2634 티켓은 고치지 않을 것 (wontfix)로 닫혀 있지만, 아드리안의 유의 한

"또는 우리가 뭔가를 누락을?" 의견에 - 아마도 언젠가 재 방문 될 것입니다.