Idiomatic Scala: no, you can't. You have specifically said that the first argument is no longer relevant. If the compiler can make it disappear entirely, that's best: you say you have a function that depends on an int and a string, and you haven't made any promises about what generated it. If you really need that value, but you also really need to pass a 2-argument function, you can do it by hand:
class Function2From3[A,B,C,Z](f: (A,B,C) => Z, val _1: A) extends Function2[B,C,Z] {
def apply(b: B, c: C) = f(_1, b, c)
}
val lowerDoStuff = new Function2From3(doStuff _, 3)
Now when you get the function later on, you can pattern match to see if it's a Function2From3, and then read the value:
val f: Function2[Int,String,Unit] = lowerDoStuff
f match {
case g: Function2From3[_,_,_,_] => println("I know there's a "+g._1+" in there!")
case _ => println("It's all Greek to me.")
}
(if it's important to you that it be an integer, you can remove A
as a generic parameter and make _1
be an integer--and maybe just call it lower
while you're at it).
Reflection: no, you can't (not in general). The compiler's smarter than that. The generated bytecode (if we wrap your code in class FuncApp
) is:
public final void apply(int, java.lang.String);
Signature: (ILjava/lang/String;)V
Code:
0: aload_0
1: getfield #18; //Field $outer:LFuncApp;
4: iconst_3
5: iload_1
6: aload_2
7: invokevirtual #24; //Method FuncApp.doStuff:(IILjava/lang/String;)V
10: return
Notice the iconst_3
? That's where your 3 went--it disappeared into the bytecode. There's not even a hidden private field containing the value any more.