Scala 具有部分应用函数的变量参数

Scala 具有部分应用函数的变量参数,scala,variadic-functions,partialfunction,Scala,Variadic Functions,Partialfunction,我对以下代码有编译问题 object Main { def main(args:Array[String]) = { def collectBigger(median:Int)(values:Int*) = values.filter { _ > median } val passedRanks = collectBigger(5)_ //this compiles println(passedRanks(Seq(5,9,5,2,1,

我对以下代码有编译问题

object Main {
    def main(args:Array[String]) = {
      def collectBigger(median:Int)(values:Int*) = values.filter { _ > median }
      val passedRanks = collectBigger(5)_
      //this compiles
      println(passedRanks(Seq(5,9,5,2,1,3)))
      //this doesn't
      println(passedRanks(5,9,5,2,1,3))
    }
}
该示例的灵感来自com.agical.gsl,它是swt的scala适配器。我假设它在Scala2.8之前使用了scala特性

错误是trait Function1中的method apply:(v1:Seq[Int])Seq[Int]的参数太多,并且与变量参数如何传递给部分应用的函数有关


感谢您提供的任何提示。

简单地说,您可以在scala中使用varargs方法,但不能使用varags函数。为什么?所有函数都有一个
函数n[T1..TN,R]
类型。在您的例子中,它是
Function1[Seq[Int],Seq[Int]]


“varargs函数”根本没有类型,因此每当您将方法转换为函数时,必须将其分解为
Seq..
符号。

您过去可以:

$ scala210 -Yeta-expand-keeps-star
Welcome to Scala version 2.10.5 (OpenJDK 64-Bit Server VM, Java 1.7.0_95).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def f(vs: Int*) = vs.sum
f: (vs: Int*)Int

scala> f(1,2,3)
res0: Int = 6

scala> val g = f _
g: Int* => Int = <function1>

scala> g(1,2,3)
res1: Int = 6
$scala210-耶塔星
欢迎使用Scala版本2.10.5(OpenJDK 64位服务器虚拟机,Java 1.7.0_95)。
键入要计算的表达式。
键入:有关详细信息的帮助。
scala>def(vs:Int*)=vs.sum
f:(vs:Int*)Int
scala>f(1,2,3)
res0:Int=6
scala>val g=f_
g:Int*=>Int=
scala>g(1,2,3)
res1:Int=6
但现在不是了


一种解决方法,根据Rob Norris的建议,使用apply值

object Main {
  def main(args: Array[String]) = {
    {
      //workaround use Seq as requested
      def collectBigger(median: Int)(values: Int*) = values.filter { _ > median }
      val passedRanks = collectBigger(5)_
      println(passedRanks(Seq(5, 9, 5, 2, 1, 3)))
      println(passedRanks(5, 9, 5, 2, 1, 3))//compile error: too many arguments for method apply: (v1: Seq[Int])Seq[Int] in trait Function1
    }

    {
      //
      def collectBigger(median: Int) = new { def apply(values: Int*) = values.filter { _ > median } }
      val passedRanks = collectBigger(5)
      import scala.language.reflectiveCalls
      println(passedRanks(Seq(5, 9, 5, 2, 1, 3)))//compile error (as expected): type mismatch; found : Seq[Int] required: Int

      //this now works
      println(passedRanks(5, 9, 5, 2, 1, 3))
    }
  }
}

当您部分应用函数时,返回函数的类型似乎是
Seq[Int]=>Seq[Int]=
。但是,如果您在不部分应用的情况下同时应用这两个参数,它确实可以正常工作。我也想知道您为什么会遇到这种行为,但您的代码在我的ide中运行良好。我的scala版本是2.11.7,发生了什么事?我在eclipse和sbt中的scala 2.11.8和scala 2.10.6中都遇到了相同的错误。