Wonay
Wonay

Reputation: 1250

Is it possible in scala to have a generic method taking a method as an argument?

I would like to have:

def myMethod[T < ???](f: T): Unit = {
    f()
}

The rest of the method is not really important but is it possible to replace ??? by somethind which would make sure T is a method

and if possible to go even further and make sure the return type of T is something defined ?

Like [T < (_*) => Int]

Thank you.

Upvotes: 0

Views: 66

Answers (3)

GatorCSE
GatorCSE

Reputation: 158

You can use function literals:

def myMethod[A, T](f: A => T) {
  f(someAValue)
}

or if you want functions that take no arguments:

def myMethod[T](f: () => T) {
  f()
}

But judging by your comments, it seems like you specifically want to reference methods, and query the method for information about itself, which is not a feature of basic Scala. You may be able to do some of that with reflection, but reflection is an area best avoided.

Upvotes: 1

Alvaro Carrasco
Alvaro Carrasco

Reputation: 6172

Technically, you can't directly pass a method, since a method is not a value that you can instantiate and pass-around. What is usually passed around is a function instance. And when it appears that you're passing a method, the compiler is actually creating a function instance for you (method lifting or eta-expansion).

But that is not going to work if you're looking to inspect meta data about that method (name, deprecation). For that, you're probably looking for reflection. You can have your method take an instance of java.reflect.Method but that will require that you obtain that at call-site.

Upvotes: 0

Leo C
Leo C

Reputation: 22449

Would defining a type, like in the following trivial example, address your need?

type Fcn = String => Int

def myMethod(s: String, f: Fcn): Unit = {
  println(f(s))
}

myMethod("hello", (s: String) => s.length)
// 5

Upvotes: 1

Related Questions