Is it possible to have syntax like (parameter1, parameter2) applied myFunction
. Here myFunction would be applied to the given parameters. Concrete example: val myFunction = (a:String) => a+a+"there"; "hello" applied myFunction
should output "hellohellothere".
I know it's possible to do (parameter1, parameter2) match {case myFunctionWrittenOut}
, so the above would become "hello" match {case a:String => a+a+"there"}
but here you have to write out the function: you can't use a reference.
问题:
回答1:
I don't think it's possible with standard scala. But you can write some helper methods that would make something like this available:
implicit class Applied1[T](val t: T) extends AnyVal {
def applied[R](f: T => R): R = f(t)
}
implicit class Applied2[T1, T2](val t: (T1, T2)) extends AnyVal {
def applied[R](f: (T1, T2) => R): R = f(t._1, t._2)
}
implicit class Applied3[T1, T2, T3](val t: (T1, T2, T3)) extends AnyVal {
def applied[R](f: (T1, T2, T3) => R): R = f(t._1, t._2, t._3)
}
// ... and 19 more implicit classes: Applied4 to Applied22
And then you can use it like this:
def minus(a: Int): Int = -a
def plus(a: Int, b: Int): Int = a + b
def plus(a: Int, b: Int, c: Int): Int = a + b + c
scala> 5 applied minus
res0: Int = -5
scala> (1, 2) applied plus
res1: Int = 3
scala> (1, 2, 3) applied plus
res2: Int = 6
But this may be a bit more complex to use with generic functions, or functions with implicit arguments:
def mul[T : Numeric](a: T, b: T): T = {
import Numeric.Implicits._
a * b
}
scala> (1.5, 2.5) applied (mul(_, _))
res3: Double = 3.75
回答2:
Implicit classes can be used to achieve something which which seems to be similar to what you are looking for.
An implicit class with only one constructor argument can be used as a pattern to add methods to the a given type. One example is DurationInt
which "adds" methods to integers to enable converting them to durations. It is imported into scope using import scala.concurrent.duration._
A simplified version of DurationInt could be defined as follows:
implicit class DurationInt(n: Int) {
def seconds: FiniteDuration = Duration(n, TimeUnit.SECONDS)
}
This enables use of the seconds method on all integers
2.seconds // Returns a duration object
For functions with multiple arguments you can use a tuple argument for the implicit class:
implicit class TupleConcat(tuple: (String, String)) {
def concat: String = tuple._1 + tuple._2
}
// enables the following syntax
("aa", "bb").concat
It is common for implicit classes such as these to extend AnyVal, this allows some compiler optimizations which avoid actually having to instantiate the implicit class in many cases.
implicit final class DurationInt(val n: Int) extends AnyVal { /* implementation */ }
回答3:
In Scala, the parameter list of a function is always written before the function:
val fn = (a: Int, b: Int) => a + b
// ^ parameters ^ ^ function