2011-05-18 153 views
3

我讀在Scala編程,不明白爲什麼這個摺疊操作是不正確的:這個摺疊爲什麼不正確?

val fruit = List("apples", "oranges", "lemons") 
println((0/:fruit)(_.length+_.length)) 

我也試圖與空字符串「」爲出發值 - 但沒有任何編譯:

println((""/:fruit)(_.length+_.length)) 

回答

8

嘗試這種情況:

println((0 /: fruit)(_ + _.length)) 

的傳遞函數接收作爲參數第一累加器(一個Int,如從您的初始值0推斷出),然後是集合的下一個元素(String,從fruit的類型推斷出)。

參數的順序很容易記住,因爲它們對應於初始值和集合的出現順序。這裏,初始值首先出現,因此,累加器作爲第一個參數傳遞 - 並且作爲第二個參數,您將獲得集合fruit的一個元素,該元素出現在方法名稱/:之後。

如果你做了一個foldRight相反,爲了將可以方便地逆轉:

println((fruit :\ 0)(_.length + _)) 
+0

活泉,工程。我怎麼沒有想到這一點! – drozzy 2011-05-18 13:35:33

6
println((0 /: fruit)(_ + _.length)) 

傳遞到摺疊該函數的兩個參數(acc, elem)的功能中acc是累加器和有與種子0elem相同的類型與列表中的元素具有相同的類型。

,如果你使用它可以更清楚:

(0 /: fruit){ (acc, elem) => acc + elem.length } 

(編輯:我最初說的元組,我已經改變到的兩個參數功能)

3

foldLeft(或/ :)需要(如第二個參數)一個帶有兩個參數的函數: 累加器和列表成員類型的變量。

所以,一個應該得到:

(0/:fruit)((acc:Int,el:String) => acc + el.length) 

這就是說

(0/:fruit)(_ + _.length)