Yes, you can, although the syntax is arguably horribly clunky, and there are some limitations that may seem a little arbitrary at first. The trick is to convert the method to a function (called "eta expansion"), and then to use that function's tupled
method to get something you can apply to a tuple.
Suppose you have a class like this:
class Foo {
def f(a: String, b: String) = "%s, %s".format(b, a)
def g(x: Int, y: Int, z: Int) = x + y * z
}
And an instance:
val foo = new Foo
And some data you'd like to use Foo
's methods on:
val names = ("John", "Doe")
val nums = (42, 3, 37)
You can't just write foo.f(names)
or foo.g(nums)
, because the types don't line up—argument lists and tuples are different things in Scala. But you can write the following:
scala> (foo.f _).tupled(names)
res0: String = Doe, John
scala> (foo.g _).tupled(nums)
res1: Int = 153
Sticking the underscore after the method turns it into a function (this is in my opinion the most confusing little quirk of Scala's syntax), and tupled
converts it from a function with two (or three) arguments to a function with a single tuple argument.
You could clean the code up a little by defining the following helper functions, for example:
scala> val myF = (foo.f _).tupled
myF: ((String, String)) => String = <function1>
scala> val myG = (foo.g _).tupled
myG: ((Int, Int, Int)) => Int = <function1>
scala> myF(names)
res2: String = Doe, John
scala> myG(nums)
res3: Int = 153
I'm not sure that's much better, though.
Lastly, you can't (conveniently) use this approach on a varargs method—you can't for example write the following:
val coordsTupleToString = ("(%4.1f, %4.1f) to (%4.1f, %4.1f)".format _).tupled
Or even just:
val coordsToString = "(%4.1f, %4.1f) to (%4.1f, %4.1f)".format _
Which is yet another reason to avoid varargs in Scala.