从scala中的部分应用函数获取参数

Jai*_*rge 1 scala currying partial-application

scala中是否有一种方法可以从已经部分应用的函数中获取参数?

这是否有意义,应该完成,还是适合任何用例?

例:

def doStuff(lower:Int,upper:Int,b:String)= for(turn <- lower to upper) println(turn +": "+b)

想象一下,我一度知道'较低'的论点,我得到一个将它应用于'doStuff'的功能

val lowerDoStuff = doStuff(3,_:Int,_:String)

有没有办法让我回来?(例如,假设我在一个只收到'lowerDoStuff'并且现在需要知道第一个参数的函数内)

习惯性scala更喜欢内省/反思(如果可能的话).

Rex*_*err 7

惯用斯卡拉:不,你不能.你已经明确地说第一个论点不再相关了.如果编译器可以使它完全消失,那就是最好的:你说你有一个依赖于int和字符串的函数,并且你没有对生成它的东西做出任何承诺.如果你真的需要这个值,但你真的需要传递一个2参数函数,你可以手工完成:

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)
Run Code Online (Sandbox Code Playgroud)

现在,当您稍后获得该函数时,您可以模式匹配以查看它是否为Function2From3,然后读取值:

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.")
}
Run Code Online (Sandbox Code Playgroud)

(如果对你来说重要的是它是一个整数,你可以删除A作为泛型参数并使其_1成为一个整数 - 也许只是lower在你的时候调用它).

反思:不,你不能(不一般).编译器比那更聪明.生成的字节码(如果我们包装你的代码class FuncApp)是:

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
Run Code Online (Sandbox Code Playgroud)

请注意iconst_3?这就是你的3去了 - 它消失在字节码中.甚至没有隐藏的私有字段包含该值.