2012-12-05 55 views
1

有人可以從REPL解釋下面的輸出嗎?Scala Stream By One

我正在定義2個(無限)流,除非之前有,否則其定義相同。一個定義中的(句點)和另一箇中的__(空格)。

我可以看到,這會導致地圖綁定不同,但會發生什麼情況輸出從第二個定義?

謝謝。

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 

回答

11

這是關於method associativity。這:

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

是相當簡單的,而這一點:

1 #:: infinite2 map(_+1) 

是由編譯器解釋爲:

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

1 #:: infinite2是你所需的視頻流,但是你回到它之前,你申請懶惰轉換爲每個項目添加一個。這就解釋了爲什麼1從未出現過 - 在轉換後它變成了2

詳情請參閱:Operator precedence in Scala。由於#不是特殊字符,因此它與map同等對待,因此方法從左到右進行評估。

+0

酷!得到它了。謝謝! –

+0

@BillBarrington:沒問題。如果您的問題得到解決,請接受/ upvote或其他答案。 –

1

在infinite2情況下,你已經表達等同於以下內容:

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

由於流從1開始,地圖將增加1到第一個元素。