开发者

Scalas (a,b).zipped (or Tuple2.zipped) notion using streams/infinite lists

开发者 https://www.devze.com 2023-02-16 12:33 出处:网络
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(_+_)

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号