2011-05-18 126 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)