As Steve said, the "..." are just ellipsis, indicating that a variable number of parameters that are not being shown.
Let's go to the Scaladoc, and show this step by step:
def foldRight[B](z: B)(op: (B, A) ⇒ B): B
That doesn't show enough. What is A
? That is defined in the Iterable
class (or whatever other class it is defined for):
trait Iterable[+A] extends AnyRef // Scala 2.7
trait Iterable[+A] extends Traversable[A] with GenericTraversableTemplate[A, Iterable[A][A]] with IterableLike[A, Iterable[A]] // scala 2.8
Ok, so A
is the type of the collection. In your example, A
would stand for Int
:
val elems = args map Integer.parseInt
Next, [B]
. That's a type parameter. Basically, the following two calls are identical in practice, but the first has the type parameter inferred by the compiler:
elems.foldRight(0) (_ + _)
elems.foldRight[Int](0) (_ + _)
If you used 0L
instead of 0
, then B
would stand for Long
instead. If you passed a ""
instead of 0
, then B
would stand for String
. You can try these out, they all will work.
So, B
is Int
and z
is 0
. Note that there are two sets parenthesis in the declaration. That means the function is curried. It receives two sets of parameters, beyond, as well as the type parameter ([B]
). What that means is that you can ommit the second set of parameter, and that will return a function which takes that second set of parameter, and returns the expected result. For example:
val elemsFolder: ((Int, Int) => Int) => Int = elems.foldRight(0)
Which you could then call like this:
elemsFolder(_ + _)
Anyway, the second set receives op
, which is expected to be of type (B, A) => B
. Or, in other words, a function which receives two parameters -- the first being the same type as z
, and the second being the same type as the type of the collection -- and returns a result of the same type as the first parameter. Since both A
and B
are Int
, it will be a function of (Int, Int) => Int
. If you passed ""
, then it would be a function of type (String, Int) => String
.
Finally, the return type of the collection is B
, which means whatever is the type of z
, that will be the type returned by foldRight
.
As for how foldRight
works, it goes a bit like this:
def foldRight[B](z: B)(op: (B, A) => B): B = {
var acc: B = z
var it = this.reverse.elements // this.reverse.iterator on Scala 2.8
while (!it.isEmpty) {
acc = op(acc, it.next)
}
return acc
}
Which, I hope should be easy enough to understand.