简体   繁体   中英

What is the supertype of all functions in Scala?

I know I can do instanceOf checks against Function1 or Function2 etc but is there a generic way to see if something is function or not (it can have arbitray number of args). I tried defining something like this:

type FuncType = (Any*) -> Any

But that did not work either. Basically I have some code that looks like this:

call = (name: Any, args: Any*) -> if name.isFunction then name.castAs[Function].apply(args) else name
aFunction = (name: String) => "Hello " + name
notAFunction = "Hello rick"
call(aFunction, "rick")
call(notAFunction)

There is no general supertype for all function types.

Scala has no way to abstract over the arity of a function. However, you might look into the Shapeless library, which introduces something called an HList that you can use for abstracting the arity of functions.

However, I'm thinking that's not really what you need. It sounds like you just want to do a check like "is this a function?" You might think it's weird that there's no arity-agnostic Function supertype, but you'd pretty much always need to know the arity of a function if you want to do something useful with it.

Alternatively, you might be able to do something with the curried method on the function, which will return a Function1 .

No, there is no way to do this, except to go through and check each of Function1 , Function2 , etc. The parent of each of these traits is AnyRef , which won't help you to distinguish them from anything else. The apply method for each of these traits takes a different number of parameters, so there is no way to give them a parent that has an apply method. The closest you could probably get to what you are trying to do is:

def arbitraryFunction(function: AnyRef, args: Seq[Any]): Any = {
  function match {
    case f: Function1[Any, Any] => f(args(0))
    case f: Function2[Any, Any, Any] => f(args(0), args(1))
    // and so on
  }
}

But this is insane and dangerous and will throw exceptions at runtime if the types are wrong, eg

arbitraryFunction((x: Int) => x * 2, List("I'm a String!"))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM