I'm not a Scala expert, and I'm confused about the syntax of calling a method with an implicit parameter.
Here's my situation:
I have a Spark RDD like this:
val myData: RDD[Array[String]] = ...
and have defined an Ordering for it:
object MyOrdering extends Ordering[Array[String]] = ...
I want to filter this RDD and take the top n entries in the RDD according to my Ordering. A Spark RDD has a method for taking the top n entries with this signature:
def top(num: Int)(implicit ord: Ordering[T]): Array[T]
Initially I tried this code
myData filter { D =>
D(9) == "yes"
} top(50)(MyOrdering)
Which fails with this error:
error: Int(50) does not take parameters
} top(50)(MyOrdering)
However, this code works:
myData.filter(D => D(9) == "yes").top(50)(MyOrdering)
To my beginner's eye, the failing code sample and the working code sample look to be specifying equivalent logic. Am I wrong here? Am I actually doing something different in the two code samples? Or is this an issue with how the Scala compiler parses the code?
You can only replace the dot .
with a space for method invocation when the method is arity-1 (1 parameter list) or arity-0 (no parameter lists). For example, this fails to compile:
class Foo {
def baz(x: Int)(y: Int) = this
def qux(x: Int) = this
}
(new Foo) baz(1)(1) //Does not compile
(new Foo).baz(1)(1) //Allowed
(new Foo) qux(1) //Allowed, since qux is arity-1
(new Foo).qux(1) //Also allowed, of course
When the the last parameter list is implicit
the compiler can treat a method with n
parameter lists as if it has arity n-1
if the method is being invoked with an implicit
argument:
class Foo {
def baz(x: Int)(implicit y: Int) = this
}
implicit val y: Int = 1
(new Foo) baz(1) //Allowed
(new Foo).baz(1) //Also fine
(new Foo) baz(1)(2) //Still not allowed
(new Foo).baz(1)(2) //Still allowed
Read more about the rules for method invocation in the style guide.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With