here is what I thought would be a correct and useful definition of fibonacci nums in scala:
lazy val fibs:Stream[Int] = 0 #:: 1 #:: (fibs,fibs.tail).zipped.map(_+_)
However, I get the following error:
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$.new开发者_JAVA百科Builder(Stream.scala:483)
at...
I guess zipped doesn't work correctly with streams? Any suggestions on how to make this work, or why this doesnt( shouldn't? ) work?
The following works correctly
val fibs:Stream[Int] = 0 #:: 1 #:: (fibs zip fibs.tail).map{ case (a,b) => a+b }
The problem with Tuple2.zipped
is that it assumes it can run foreach
on sequences it's zipping. This is probably by design, as doing things the way Stream.zip
implements it would probably give you bad performance for any finite-length Seq
that isn't a List
or Stream
. (Because most data structures don't support an efficient implementation of tail
.)
Stream.zip
is essentially implemented as follows (though it does some stuff to make the types more general).
class Stream[A]{
def zip(other:Stream[B]) =
(this.head, other.head) #:: (this.tail zip other.tail)
}
There's a ticket on this in Scala's Trac database: http://lampsvn.epfl.ch/trac/scala/ticket/2634
The ticket was closed as wontfix, but note Adriaan's "Or are we missing something?" in the comments — maybe this will get revisited someday.
精彩评论