Can someone please explain the following output from the REPL?
I’m defining 2 (infinite) Streams that are otherwise identical in their definition except that map is preceded by . (period) in one definition and a _ _ (space) in the other.
I can see that this would cause map to bind differently, but what happens to the 1 in the output from the second definition?
Thanks.
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
It’s about method associativity. This:
is quite straightforward while this:
is interpreted by the compiler as:
1 #:: infinite2is your desired stream, but before you return it, you apply lazy transformation adding one to every item. This explains why1never appears as a result – after transformation it becomes2.For more details see: Operator precedence in Scala. Since
#is not a special character, it is treated equally withmap, thus methods are evaluated from left to right.