斯卡拉流一个人

时间:2012-12-05 18:27:46

标签: scala map stream

有人可以解释一下REPL的以下输出吗?

我定义的2个(无限)流在定义上是相同的,只是 map 在一个定义中以(句点)开头,并且_ _ (空间)在另一个。

我可以看到这会导致 map 绑定不同,但第二个定义的输出中 1 会发生什么?

感谢。

scala> lazy val infinite: Stream[Int] = 1 #:: infinite.map(_+1)
infinite: Stream[Int] = <lazy>

scala> val l = infinite.take(10).toList.mkString(",")
l: String = 1,2,3,4,5,6,7,8,9,10

scala> lazy val infinite2: Stream[Int] = 1 #:: infinite2 map(_+1)
infinite2: Stream[Int] = <lazy>

scala> val l2 = infinite2.take(10).toList.mkString(",")
l2: String = 2,3,4,5,6,7,8,9,10,11

2 个答案:

答案 0 :(得分:11)

关于method associativity。这样:

1 #:: infinite.map(_+1)

非常简单:

1 #:: infinite2 map(_+1)

由编译器解释为:

(1 #:: infinite2) map(_+1)

1 #:: infinite2是您想要的流,但在您返回之前,您应用延迟转换,为每个项添加一个。这解释了为什么1永远不会出现的结果 - 转换后它变为2

有关详细信息,请参阅:Operator precedence in Scala。由于#不是特殊字符,因此它与map同等对待,因此方法从左到右进行评估。

答案 1 :(得分:1)

在无限的情况下,你所表达的内容相当于以下内容:

lazy val infinite2: Stream[Int] = (1 #:: infinite2) map(_ + 1)

由于流以1开头,因此地图将向第一个元素添加1。