Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Passing Function with Argument

The Scala example for passing a function to another function lacks the case where the passed function (timeFlies) takes an argument (x).

object Timer {
  def oncePerSecond(callback: (Int) => Unit) {
    while (true) { callback(x); Thread sleep 1000 }
  }
  def timeFlies(x: int) {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies(5))
  }
}

How can I make the above code work?

Edit: I added an x in the oncepersecond to clarify the goal is to pass the integer.

like image 967
BAR Avatar asked Dec 11 '14 22:12

BAR


People also ask

How do you pass parameters to a function in Scala?

Scala - Functions with Named Arguments Named arguments allow you to pass arguments to a function in a different order. The syntax is simply that each argument is preceded by a parameter name and an equals sign. Try the following program, it is a simple example to show the functions with named arguments.

What is the meaning of => in Scala?

=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .

Can a function take a function as an argument?

Because functions are objects we can pass them as arguments to other functions. Functions that can accept other functions as arguments are also called higher-order functions.


2 Answers

There are at least two ways you can do it, depending on where exactly you want to pass the argument in. The first way is where you keep main like you had it.

object Timer {
  def oncePerSecond(callback: => Unit) {
    while (true) { callback; Thread sleep 1000 }
  }
  def timeFlies(x: Int) {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies(5))
  }
}

The other method is to pass the parameter in at the point of the callback, like this:

object Timer {
  def oncePerSecond(callback: (Int) => Unit) {
    val x = 5
    while (true) { callback(x); Thread sleep 1000 }
  }
  def timeFlies(x: Int) {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies)
  }
}

Note that timeFlies has the signature (Int) => Unit, but timeFlies(5) has the signature => Unit, because of partial application. This basically means you can apply the parameter to automatically create a function that takes fewer parameters. oncePerSecond needs to know in its signature if you've already applied the Int parameter to the callback or not.

Both methods are useful for different use cases. The first way lets oncePerSecond not have to know about the callback's parameters. The second way lets you change the value of x every time through the loop if you want.

like image 119
Karl Bielefeldt Avatar answered Oct 06 '22 07:10

Karl Bielefeldt


The return type of timeFlies will be Unit, not Function. Perhaps you meant:

oncePerSecond(() => timeFlies(5))
like image 35
John Avatar answered Oct 06 '22 08:10

John