使用流/无限列表的Scalas(a,b).zipped(或Tuple2.zipped)概念

时间:2011-03-11 17:56:24

标签: list scala stream fibonacci infinite

这里是我认为scala中斐波纳契词的正确和有用的定义:

lazy val fibs:Stream[Int] = 0 #:: 1 #:: (fibs,fibs.tail).zipped.map(_+_)

但是,我收到以下错误:

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$.newBuilder(Stream.scala:483)
    at...

我猜压缩无法正常使用流?关于如何使这项工作的任何建议,或为什么这不起作用(不应该?)?

2 个答案:

答案 0 :(得分:8)

以下工作正常

val fibs:Stream[Int] = 0 #:: 1 #:: (fibs zip fibs.tail).map{ case (a,b) => a+b }

Tuple2.zipped的问题在于它假设它可以在它正在压缩的序列上运行foreach。这可能是设计的,因为按Stream.zip实现它的方式做事可能会给任何不是SeqList的有限长度Stream带来不良表现。 (因为大多数数据结构不支持tail的有效实现。)


Stream.zip基本上实现如下(虽然它做了一些使得类型更通用的东西)。

class Stream[A]{
  def zip(other:Stream[B]) =
    (this.head, other.head) #:: (this.tail zip other.tail)
}

答案 1 :(得分:3)

在Scala的Trac数据库中有一张票:http://lampsvn.epfl.ch/trac/scala/ticket/2634

票据被关闭为wontfix,但请注意Adriaan的“或者我们错过了什么?”在评论中 - 也许有一天会重新审视。