Distribution options in Scala?

Is there a way to call the Scala function, which accepts individual parameters, given the array (similar to JavaScript   Spreads in ECMAScript 6)?

ys = [10.0, 2.72, -3.14]
f(x, ...ys);

The cleanest syntax:

f(1, ys)

but this is not possible. It f(1, ys:_*)doesn’t even work (and doesn’t f(ys:_*), because the compiler reports too few parameters - only the first one is filled).

Example:

def f (a:Int, b:Float, c:Float, d:Float): String

val x  = 1
val ys = List(10.0, 2.72, -3.14)  // note: non-Objects
val result = f(x, ys)  // intuitive, but doesn't work

Use case: input of test data (from collections) into existing methods that take separate parameters. Since these are test cases, it is quite normal if #params in ys does not match, and this gives either a runtime error or an incorrect result.

, Scala , , - ( , , ).

+5
2

, ( ). , :

"My hack" should {
  "allow a function to be called with Lists" in {

    def function(bar:String, baz:String)= bar+baz


    //turn the function into something that accepts a tuple
    val functionT = function _
    val functionTT = functionT.tupled

    val arguments = List("bar", "baz")

    //Give the compiler a way to try and turn a list into a tuple of the size you need
    implicit def listToTuple(args:List[String]) = args match { 
      case List(a, b) => (a, b)
      case _ => throw IllegalArgumentException("Trying to pass off %s as a pair".format(args))
    }

    //Shove it in and hope for the best at runtime
    val applied = functionTT(arguments)
    applied === "barbaz"
  }
}

, , Schönfinkeling . .

, , . , , , . ?

Spray, , . , , . , .

+3

, .

scala> object Foo {
 | def doFoo(i:Int, s:String) = println(s * i)
 | }

defined module Foo

scala> val fooFunc = Foo.doFoo _
fooFunc: (Int, String) => Unit = <function2>

scala> val applyMeth = fooFunc.getClass.getMethods()(0)
applyMeth: java.lang.reflect.Method = public final void $anonfun$1.apply(int,java.lang.String)

scala> val i:Integer = 5

i: Integer = 5

scala> val seq = Seq[Object](i,"do the foo! ")
seq: Seq[Object] = List(5, "do the foo! ")

scala> applyMeth.invoke(fooFunc, seq :_*)
do the foo! do the foo! do the foo! do the foo! do the foo! 
res59: Object = null

, DSL , . , , - .

Rubistro .

a) foo.doFoo? ( - , doFoo.)

val fooFunc - Function2, , , applyMeth.invoke(fooFunc, seq :_*).

b) doFoo seq?

. , . , , / , , . , ,

class InvokationBuilder(meth:java.lang.reflect.Method, args: List[Object] = Nil) {
    def invoke(instance:Object) = meth.invoke(instance, args.toSeq :_*)
    def append(arg:Object) = new InvokationBuilder(meth, args :+ arg)
    def prepend(arg:Object)= new InvokationBuilder(meth, arg :: args)
}
+3

All Articles