我將從引用開始Scala編程。 「每個表達式都可以用三個高階函數map,flatMap和filter來表示。這部分描述了Scala編譯器也使用的翻譯方案。「 http://www.artima.com/pins1ed/for-expressions-revisited.html#23.4
因此,您注意到for-loops的原因並不多,因爲它們在技術上並不需要,而且對於表達式你看到的僅僅是語法糖,編譯器會翻譯成一些等價的語法。上面的鏈接中列出了將表達式翻譯成map/flatMap/filter表達式的規則:
一般來說,在函數式編程中,沒有索引變量可以進行變異,這意味着通常會大量使用函數調用(通常以遞歸的形式),比如列表摺疊而不是一段時間或循環。
對於使用列表摺疊來代替while/for循環的一個很好的例子,我推薦Tony Morris的「向你自己解釋列表摺疊」。 https://vimeo.com/64673035
如果一個函數是尾遞歸的(用@tailrec表示),那麼它可以進行優化,以避免在遞歸函數中高度使用堆棧。在這種情況下,編譯器可以將尾遞歸函數轉換爲「while循環等效」。
要回答問題1的第二部分,有些情況下可以說一個for表達式更清楚(儘管肯定也有相反的情況。)一個這樣的例子在Coursera.org課程「Scala的函數編程」由馬丁·奧德斯基博士:
for {
i <- 1 until n
j <- 1 until i
if isPrime(i + j)
} yield (i, j)
可以說是比
(1 until n).flatMap(i =>
(1 until i).withFilter(j => isPrime(i + j))
.map(j => (i, j)))
更清晰欲瞭解更多信息,請查閱馬丁·奧德斯基博士的「函數式編程使用Scala」當然在Coursera.org上。第6.5講「For的翻譯」特別詳細討論了這一點。
而且,作爲一個快速側面說明,在您的例子中,你使用
mapper.map(x => println(x))
人們普遍所接受使用的foreach在這種情況下,因爲你有副作用的意圖。此外,還有手短
mapper.foreach(println)
至於第二個問題,這是更好地使用地圖功能替代循環(尤其是當有突變的循環),因爲地圖是一個功能,它可以由。而且,一旦熟悉並習慣使用地圖,就很容易推理。
對於您給(打印輸出)的例子,您不會使用map,但會使用iter。當你將一個集合元素從類型A轉換爲類型B時,映射就是你所使用的。 – BitTickler
請注意,Scala中的'for'循環被編譯器轉換爲包括'map'和'flatMap'在內的操作 - 參見[this question]( http://docs.scala-lang.org/tutorials/FAQ/yield.html),例如 – DNA
@DNA所以for循環只是一個合成糖,它將被編譯器轉換爲map和flatMap。 – Knight71