具有部分应用函数的可变参数
Variable arguments with partial applied functions
我对以下代码有编译问题。
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 适配器。我假设它在 scala 2.8 之前使用了 scala 功能。
错误是 too many arguments for method apply: (v1: Seq[Int])Seq[Int] in trait Function1
并且与如何将变量参数传递给部分应用的函数有关。
感谢您提供的任何提示。
简单地说,你可以在 scala 中使用可变参数方法,但不能使用可变参数函数。为什么?好吧,所有函数都有一个 FunctionN[T1..TN,R]
类型。在您的情况下,它是 Function1[Seq[Int], Seq[Int]]
.
"varargs function" 根本没有类型,因此无论何时将方法转换为函数,都必须将其脱糖为 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
但现在不是了。
根据 Rob Norris
的建议,应用值的解决方法
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))
}
}
}
我对以下代码有编译问题。
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 适配器。我假设它在 scala 2.8 之前使用了 scala 功能。
错误是 too many arguments for method apply: (v1: Seq[Int])Seq[Int] in trait Function1
并且与如何将变量参数传递给部分应用的函数有关。
感谢您提供的任何提示。
简单地说,你可以在 scala 中使用可变参数方法,但不能使用可变参数函数。为什么?好吧,所有函数都有一个 FunctionN[T1..TN,R]
类型。在您的情况下,它是 Function1[Seq[Int], Seq[Int]]
.
"varargs function" 根本没有类型,因此无论何时将方法转换为函数,都必须将其脱糖为 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
但现在不是了。
根据 Rob Norris
的建议,应用值的解决方法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))
}
}
}