Can I pass an arbitrary function to another function in Scala?

Dan Barowy picture Dan Barowy · Jun 14, 2011 · Viewed 8k times · Source

I'm new to Scala, and being able to pass functions to other functions is pretty neat-- but can I pass an arbitrary function reference to another function? The arity of said functional parameter will be fixed (that said, I'm also curious about whether you can pass a function with arbitrary arity as well). I keep getting tripped up on type errors. I've tried using Any but it doesn't seem to help.

E.g., I have the code below:

class CodeRunner(val user_defined: (Int) => Unit) {
  def run(input: Int) = {
    user_defined(input)
  }
}

def arbitrary_code(input: Int) = { println("Running with input " + input) }

val d1 = new CodeRunner(arbitrary_code)

d1.run(4)

And I get:

Running with input 4

Now, let's say that I want to pass the following function instead:

def arbitrary_code(input: String) = { println("Running with input " + input) }

How can I change my CodeRunner class to handle both?

Answer

Ben Jackson picture Ben Jackson · Jun 14, 2011

How can I change my CodeRunner class to handle both?

You can make the arbitrary type a parameter of the class:

class CodeRunner[T](val user_defined: (T) => Unit) {
  def run(input: T) = {
    user_defined(input)
  }
}

def arbitrary_code(input: Int) = { println("Running with input " + input) }

val d1 = new CodeRunner(arbitrary_code)

d1.run(4)

def arbitrary_code2(input: String) = { println("Running with input " + input) }

val d2 = new CodeRunner(arbitrary_code2)

d2.run("hello")

Note that the type of d2 is CodeRunner[String] which is not assignable to d1 which is CodeRunner[Int].