2010-06-02 9 views
7

Ich definiere einen Stream in sich selbst (eine rekursive Definition). Wenn Sie versuchen, auf das zweite Element des Streams zuzugreifen, wird StackOverflowError ausgelöst. Der Code von der Scala-Konsole:Rekursiver Stream wirft 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... 

Ich kann den Grund des Stapelüberlaufs nicht verstehen. Da Streams von Natur aus faul sind, sollte das rekursive Mapping funktionieren.

Was ist falsch an diesem Szenario?

Ich benutze Scala Version 2.8.0.RC2.

Antwort

8

Das Problem ist, dass zipped nicht faul ist - es versucht tatsächlich, die Karte genau dort auszuwerten. Sie können tun, was Sie wollen mit 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

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