2

I have a compilation problem on the following code.

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))
    }
}

The sample is inspired from com.agical.gsl which is a scala adapter to swt. I assume it used scala features before scala 2.8.

The error is too many arguments for method apply: (v1: Seq[Int])Seq[Int] in trait Function1 and is connected on how the variable arguments are passed to a partially applied function.

Thanks for any hints that you could give.

4
  • When you partially apply the function collectBigger it appears that the return function is of type Seq[Int] => Seq[Int] = <function1>. If you do however apply both arguments without partially applying it does work as you want. Commented May 30, 2016 at 13:36
  • I would also like to know why you are experiencing that kind of behaviour Commented May 30, 2016 at 13:37
  • but your code works fine in my ide. the scala version of mine is 2.11.7, what happened? Commented May 30, 2016 at 18:48
  • I get the same error in scala 2.11.8 and in scala 2.10.6 in both eclipse and sbt. Commented May 30, 2016 at 20:46

3 Answers 3

10

To put it simply, you can have a varargs method in scala, but not a varags function. Why? Well, all functions have a FunctionN[T1..TN,R] type. In your case, it is Function1[Seq[Int], Seq[Int]].

There is simply no type for a "varargs function", so whenever you convert a method to a function, it must be desugared into the Seq.. notation.

Sign up to request clarification or add additional context in comments.

Comments

0

You used to be able to:

$ 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

But no longer.

https://issues.scala-lang.org/browse/SI-6816

Comments

0

An workaround a value with apply as suggested by 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))
    }
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.