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.
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.
The return type of timeFlies
will be Unit
, not Function
. Perhaps you meant:
oncePerSecond(() => timeFlies(5))
oncePerSecond(() => timeFlies(5))
or
def oncePerSecond(callback: => Unit) {...
The parameter callback: () => Unit
is a zero-parameter function that returns Unit
. You should make it call-by-name parameter (something that evaluates to Unit
):
def oncePerSecond(callback: => Unit) = ...