Reputation: 61121
I am reading Programming in Scala, and don't understand why this folding operation is not correct:
val fruit = List("apples", "oranges", "lemons")
println( (0/:fruit)(_.length+_.length) )
I also tried with empty string "" as the starting value - but that didn't compile either:
println( (""/:fruit)(_.length+_.length) )
Upvotes: 3
Views: 176
Reputation: 41646
println( (0 /: fruit)(_ + _.length) )
The function to pass to the fold takes a function of two arguments (acc, elem)
where acc
is the accumulator and has the same type as the seed 0
, elem
has the same type as the elements of the list.
It may be clearer if you use:
(0 /: fruit){ (acc, elem) => acc + elem.length }
(edit: I initially said tuple, I've changed to function of two arguments)
Upvotes: 6
Reputation: 60006
Try this:
println( (0 /: fruit)(_ + _.length) )
The passed function receives as argument first the accumulator (an Int
, as inferred from your initial value 0
) and then the next element of the collection (a String
, inferred from the type of fruit
).
The order of the arguments is easy to remember, as they correspond to the order in which the initial value and the collection appear. Here, the initial value appears first, and accordingly, the accumulator is passed as first argument — and as second argument, you get an element of the collection fruit
, which appears after the method name /:
.
If you did a foldRight
instead, the order would be conveniently reversed:
println( (fruit :\ 0)(_.length + _) )
Upvotes: 8
Reputation: 1895
foldLeft (or /:) takes (as second argument) a function which takes two arguments: the accumulator and variable of the type of the members of the list.
So, one should get:
(0/:fruit)((acc:Int,el:String) => acc + el.length)
which is to say
(0/:fruit)(_ + _.length)
Upvotes: 3