2010-06-02 12 views
7

Definiuję strumień w kategoriach samej siebie (definicja rekursywna). Podczas próby uzyskania dostępu do drugiego elementu strumienia zostanie wygenerowany StackOverflowError. Kod z konsoli scala:Strumień rekursywny wyrzuca StackOverflowError

scala> val s1 = Stream.iterate(1)(identity _) 
s1: scala.collection.immutable.Stream[Int] = Stream(1, ?) 

scala> lazy val s2 : Stream[Int]= Stream.cons(1, (s2, s1).zipped.map { _ + _ }) 
s2: Stream[Int] = <lazy> 

scala> s1 take 5 print 
1, 1, 1, 1, 1, empty 
scala> s2(0) 
res4: Int = 1 

scala> s2(1) 
java.lang.StackOverflowError 
     at $anonfun$s2$1$$anonfun$apply$1.apply(<console>:9) 
     at $anonfun$s2$1$$anonfun$apply$1.apply(<console>:9) 
     at scala.Tuple2$Zipped$$anonfun$map$1.apply(Tuple2.scala:62) 
     at scala.collection.immutable.Stream.foreach(Stream.scala:255) 
     at scala.Tuple2$Zipped.map(Tuple2.scala:60) 
     at $anonfun$s2$1.apply(<console>:9) 
     at $anonfun$s2$1.apply(<console>:9) 
     at scala.collection.immutable.Stream$Cons.tail(Stream.scala:556) 
     at scala.collection.immutable.Stream$Cons.tail(Stream.scala:550) 
     at scala.collection.immutable.Stream.foreach(Stream.scala:256) 
     at scala.Tuple2$Zipped.map(Tuple2.scala:60) 
     at $anonfun$s2$1.apply(<console>:9) 
     at $anonfun$s2$1.apply(<console>:9) 
     at scala.collection.immutable.Stream$Cons.tail(Stream.scala:556) 
     at scala.collection.immutable.Str... 

Nie mogę zrozumieć przyczyny przepełnienia stosu. Ponieważ strumienie są z natury leniwy, mapowanie rekursywne powinno działać.

Co jest nie tak z tym scenariuszem?

Używam Scala w wersji 2.8.0.RC2.

Odpowiedz

8

Problem polega na tym, że zipped nie jest leniwy - faktycznie próbuje ocenić tę mapę właśnie tam. Możesz robić, co chcesz, dzięki zip.

scala> val s1 = Stream.iterate(1)(identity _) 
s1: scala.collection.immutable.Stream[Int] = Stream(1, ?) 

scala> lazy val s2: Stream[Int] = Stream.cons(1, (s2 zip s1).map {s=>s._1+s._2}) 
s2: Stream[Int] = <lazy> 

scala> s2 take 5 print 
1, 2, 3, 4, 5, empty 
+1

to http://lampsvn.epfl.ch/trac/scala/ticket/2634 –

Powiązane problemy