Hanxue
Hanxue

Reputation: 12766

Scala type ascription for varargs using _* cause error

I have a rudimentary understanding of Scala varargs: that parameters to a method accepting varargs need to hint that it is a varargs using _*. Using Scala 2.10.3, I define the following two methods

scala> def method(varargs:Int*)(more:String*) = println(varargs,more)
method: (varargs: Int*)(more: String*)Unit
scala> val method2 = method(1,2,3)_
method2: Seq[String] => Unit = 

Invoking them directly using a List or Range works fine

scala> val paramList = List("hi","ho")
paramList: List[java.lang.String] = List(hi, ho)

scala> method2(paramList)
(WrappedArray(1, 2, 3),List(hi, ho))

scala> val range = (1 to 5) map {_.toString}
range: scala.collection.immutable.IndexedSeq[String] = Vector(1, 2, 3, 4, 5)

scala> method2(range)
(WrappedArray(1, 2, 3),Vector(1, 2, 3, 4, 5))

Why is it when I invoke them by ascribing the parameter with _*, I get errors?

scala> method2(paramList:_*)
<console>:11: error: type mismatch;
 found   : List[String]
 required: Seq[Seq[String]]
              method2(paramList:_*)
                      ^

scala> method2(range:_*)
<console>:11: error: type mismatch;
 found   : scala.collection.immutable.IndexedSeq[String]
 required: Seq[Seq[String]]
              method2(range:_*)
                      ^

Upvotes: 3

Views: 964

Answers (1)

senia
senia

Reputation: 38045

method2 is not a method accepting repeated parameters, it's a function with a single parameter of type Seq[String].

You should call it like this: method2(paramList) without :_*.

There is no such thing as function accepting repeated parameters in scala 2.10, but it exists in scala 2.9:

scala> def method(varargs:Int*)(more:String*) = println(varargs,more)
method: (varargs: Int*)(more: String*)Unit

scala> val method2 = method(1,2,3)_
method2: String* => Unit = <function1>

scala> val paramList = List("hi","ho")
paramList: List[java.lang.String] = List(hi, ho)

scala> method2(paramList:_*)
(WrappedArray(1, 2, 3),List(hi, ho))

Note the inferred type of method2: Seq[String] => Unit in 2.10 vs String* => Unit in 2.9.

It wasn't a useful feature: you can't use variable of type String* => Unit as a parameter or return value. Actually String* => Unit is not a valid type even in 2.9:

scala> def test(f: String* => Unit) = ()
<console>:1: error: ')' expected but '=>' found.
       def test(f: String* => Unit) = ()
                           ^

Upvotes: 8

Related Questions