Stack Over Flow:
大家好。
我想定义一个部分应用的函数,它有varargs。
为了确认,我准备了几个函数,即Functions._。 除func之外的函数都有一个varargs参数。
如何使用varargs定义和调用部分应用的函数? (例如gunc1 with varargs。)
java版“1.7.0_07” Scala代码运行器版本2.9.1.final
object Functions {
def func(x: Int, y: Int) = x + y
def gunc(x: Int*) = x.sum
def hunc(x: Int, y: Int*) = x + y.sum
def iunc(x: Int)(y: Int*) = x + y.sum // curried
def junk(x: String, y: Int*) = x + y.sum
}
object PartiallyApplied extends App {
import Functions._
val func0 = func(1, _: Int) // I can.
println("result: " + func0(2))
val gunc0 = gunc(1, _: Int) // I can invoke if I specify the varargs.size. But gunc0 no longer has varargs...
println("result: " + gunc0(2))
// val gunc1 = gunc(1, _: Int*) => compile error: ')' expected but identifier found.
// val gunc1 = gunc(1, _: Seq[Int]) => compile error: type mismatch | found: Seq[Int] | required: Int
val gunc1 = gunc(1, _: Int) // I can invoke if I specify the varargs.size. But gunc1 no longer has varargs...
println("result: " + gunc1(2))
// val hunc0 = hunc(1)_ => compile error: _ must follow method; cannot follow Int
// val hunc0 = hunc(1, _: Int*) => compile error: ')' expected but identifier found.
// val hunc0 = hunc(1, _: Seq[Int]) => compile error: type mismatch | found: Seq[Int] | required: Int
val hunc0 = hunc(1, _: Int) // I can invoke if I specify the varargs.size. But hunc0 no longer has varargs...
println("result: " + hunc0(2))
// println("result: " + hunc0(2, 3)) => compile error: too many arguments for method apply: (v1: Int)Int in trait Function1
// println("result: " + hunc0((2, 3): _*)) => compile error: type mismatch | found: (Int, Int) | required: Seq[Int]
// println("result: " + hunc0(Seq(2, 3))) => compile error: type mismatch | found: Seq[Int] | required: Int
// println("result: " + hunc0(Seq(2, 3): _*)) => compile error: no `: _*' annotation allowed here (such annotations are only allowed in arguments to *-parameters)
val hunc1 = hunc(1, _: Int, _: Int) // I can invoke if I specify the varargs.size. But hunc1 no longer has varargs...
println("result: " + hunc1(2, 3))
val hunc2 = hunc(1, _: Int, _: Int, _:Int) // I can invoke if I specify the varargs.size. But hunc2 no longer has varargs...
val hunc3 = hunc2(2, _: Int, _: Int)
val hunc4 = hunc3(3, _: Int)
println("result: " + hunc4(4))
println("result: " + hunc5(2, 3))
// val iunc0 = iunc(1)(_: Int*) => compile error: ')' expected but identifier found.
// val iunc0 = iunc(1)(_: Seq[Int]) => compile error: type mismatch | found: Seq[Int] | required: Int
val iunc0 = iunc(1)(_: Int)
println("result: " + iunc0(2))
val iunc1 = iunc(1)(_: Int, _: Int)
println("result: " + iunc1(2, 3))
}
object NotPartiallyApplied extends App {
import Functions._
println("result: " + gunc(1))
println("result: " + gunc(1, 2, 3))
println("result: " + gunc(Seq(1, 2, 3): _*))
println("result: " + hunc(1))
println("result: " + hunc(1, 2, 3))
println("result: " + hunc(1, Seq(2, 3): _*))
println("result: " + iunc(1)(2, 3))
println("result: " + iunc(1)(Seq(2, 3): _*))
println("result: " + junk("x"))
println("result: " + junk("x", 2, 3))
println("result: " + junk("x", Seq(2, 3): _*))
}
[在Rex Kerr的评论之后编辑]
我想要部分应用的功能如下面的guncN:
val guncN = gunc(1, _: Int*)
println("result: " + guncN(2)) // => 3
println("result: " + guncN(2, 3)) // => 6
println("result: " + guncN(2, 3, 4, 5, 100)) // => 115
但它被scalac禁止。
我认为应该每次评估guncN,时间(2),(2,3)和(2,3,4,5,100)。 我们下面不需要guncM:
val guncM = guncN(2, _: Int*)
println("result: " + guncM(3, 4)) // => 10
答案 0 :(得分:6)
如果你只想要varargs,你可以在2.9:
Welcome to Scala version 2.9.1.final
(Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_31).
...
scala> def sum(xs: Int*) = xs.sum
sum: (xs: Int*)Int
scala> val summer = sum _
summer: Int* => Int = <function1>
scala> summer(1,2,3)
res0: Int = 6
但不是现在的2.10,而且没有明显的改变计划:https://issues.scala-lang.org/browse/SI-4176
Welcome to Scala version 2.10.0-RC2
(Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_31).
...
scala> def sum(xs: Int*) = xs.sum
sum: (xs: Int*)Int
scala> val summer = sum _
summer: Seq[Int] => Int = <function1>
scala> summer(1,2,3)
<console>:10: error: too many arguments for method apply:
(v1: Seq[Int])Int in trait Function1
summer(1,2,3)
如果您有2.9,那么您可以
scala> def temp(early: Int*)(rest: Int*) = sum((early ++ rest): _*)
temp: (i: Int, j: Int)(rest: Int*)Int
scala> val presummed = temp(1,2) _
presummed: Int* => Int = <function1>
scala> presummed(4,5)
res1: Int = 12
但也许您不应该依赖于varargs函数,因为它似乎已经被弃用(或者至少在-Yeta-expand-keeps-star
标志后移动,-Y
选项可能无法正常工作或者随时删除。)
答案 1 :(得分:2)
我找到的解决方案是编写功能:
Welcome to Scala version 2.10.0-RC1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_37).
...
scala> 1 :: (_:Int) :: Nil : Seq[Int]
res42: Int => Seq[Int] = <function1>
scala> gunc _
res43: Seq[Int] => Int = <function1>
scala> res42 andThen res43
res54: Int => Int = <function1>
scala> res54(5)
res56: Int = 6
答案 2 :(得分:0)
也许你不应该依赖varargs函数,因为它似乎已被弃用(或者至少被移到
-Yeta-expand-keeps-star
标志之后)
SI-6816确认弃用,在Scala 2.12.x,2016年12月,PR 5558,该标志明确消失(discussion here)。
我想要一个部分功能,我们不知道
args.size
BEFOREHAND
这似乎仍然不可能(在Scala 2.12.x,2016年12月)