简体   繁体   English

Scala中所有函数的超类型是什么?

[英]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). 我知道我可以对Function1Function2等进行instanceOf检查,但是有一种通用的方法来查看某些东西是否有效(它可以具有仲裁数量的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. Scala无法对函数的arity进行抽象。 However, you might look into the Shapeless library, which introduces something called an HList that you can use for abstracting the arity of functions. 但是,您可以查看Shapeless库,它引入了一个名为HList东西,您可以使用它来抽象函数的arity。

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. 你可能会觉得奇怪的是,没有与arity无关的Function超类型,但如果你想对它做一些有用的事情,你几乎总是需要知道一个函数的arity。

Alternatively, you might be able to do something with the curried method on the function, which will return a Function1 . 或者,您可以使用函数的curried方法执行某些操作,该函数将返回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. 不,没有办法做到这一点,除了通过并检查每个Function1Function2等。每个特征的AnyRefAnyRef ,它不会帮助你区别于其他任何东西。 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. 每个traits的apply方法都使用不同数量的参数,因此无法为它们提供具有apply方法的父级。 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!"))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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