2010-06-02 7 views
7

Je définis un flux en termes de lui-même (une définition récursive). Lorsque vous essayez d'accéder au deuxième élément du flux, StackOverflowError est levé. Le code de la console scala:Flux récursif throws 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... 

Je n'arrive pas à comprendre la raison du débordement de la pile. Puisque les flux sont intrinsèquement paresseux, le mappage récursif devrait fonctionner.

Quel est le problème avec ce scénario? J'utilise Scala version 2.8.0.RC2.

Répondre

8

Le problème est que zipped n'est pas paresseux - il essaye réellement d'évaluer cette carte là. Vous pouvez faire ce que vous voulez avec 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

c'est http://lampsvn.epfl.ch/trac/scala/ticket/2634 –

Questions connexes