RafaelTSCS
RafaelTSCS

Reputation: 1314

Scala - Can I define a function that receives any function as a parameter?

Is it possible, in Scala, to define a function that would receive any other function as a parameter?

It should be something like the following:

object Module extends SecureModule{
    val bc = new MyBC()

    def method(parameter: Type) = {
        exec(bc.method(parameter))
    }
    def method2(parameter1: Type1, parameter2: Type2) = {
        exec(bc.method2(parameter1,parameter2))
    }
}

trait SecureModule {
    def exec(f: ANY_PARAMETER => ANY_RESULT) = {
        //some extra processing
        f
    }
}

is it possible? If so, how could I achieve this?

Thank you in advance.

Upvotes: 0

Views: 92

Answers (3)

Chris Scott
Chris Scott

Reputation: 1761

The nice thing about scala is that you can create what seems to be your own syntax.

If what you want to do is wrap an operation so that you can do pre and post processing, as well as control the execution context, then you do this by using call-by-name parameters. For example, if we just wanted to time how long a block of code takes, then we could do something like this:

def timer[T](block: => T): (T,Long) = {
  val startDate = new Date()
  val result = block
  val endDate = new Date()
  (result, endDate.getTime()-startDate.getTime())
}

We can use it like this:

val (result,duration) = timer {
  1+3
}

Or like this

val (result,duration) = timer {
  "hello" + " world!"
}

And the result will have the correct type from the block that you pass in while also giving you the duration that you expect.

Upvotes: 2

Sascha Kolberg
Sascha Kolberg

Reputation: 7162

I am under the impression that your description is somewhat misleading. The way I understand it, what you (might) want to do is delaying the execution of the bc.method calls until some other code has been performed. If so, try this:

object Module extends SecureModule{
    val bc = new MyBC()

    def method(parameter: Type) = {
        exec(() => bc.method(parameter))
    }
    def method2(parameter1: Type1, parameter2: Type2) = {
        exec(() => bc.method2(parameter1,parameter2))
    }
}

trait SecureModule {
    def exec[Result](f: () => Result): Result = {
        //some extra processing
        f()
    }
}

Upvotes: 1

dcastro
dcastro

Reputation: 68750

You can't take any function as a parameter. What would you even do it?

At best, you can take any function that has a specific number of parameters.

For example, here, f takes one argument and returns a value.

def exec[A,B](f: A => B)

And here, f takes two arguments:

def exec[A,B,C](f: (A, B) => C)

If you don't care about the return type of the function, you could always use Any instead of a type parameter, since functions are covariant in their return type:

def exec[A](f: A => Any)

Upvotes: 0

Related Questions