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

时间:2013-08-31 03:55:40

标签: scala reflection macros functional-programming scala-macros

我知道我可以针对instanceOfFunction1等进行Function2检查,但是有一种通用方法可以查看某些内容是否有效(它可以有多个args的仲裁数) 。我试着定义这样的东西:

type FuncType = (Any*) -> Any

但这也不起作用。基本上我有一些看起来像这样的代码:

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)

2 个答案:

答案 0 :(得分:4)

所有函数类型都没有通用的超类型。

Scala无法对函数的arity进行抽象。但是,您可以查看Shapeless库,它引入了一个名为HList的东西,您可以使用它来抽象函数的arity。

但是,我认为这不是你真正需要的。听起来你只是想做一个像“这是一个功能吗?”的检查。你可能会觉得奇怪的是,没有与arity无关的Function超类型,但如果你想用它做一些有用的事情,你几乎总是需要知道函数的优点。

或者,您可以使用函数上的curried方法执行某些操作,该方法将返回Function1

答案 1 :(得分:3)

不,除了通过并检查Function1Function2等的每个内容之外,没有办法执行此操作。每个特征的父级都是AnyRef,其中不会帮助你将它们与其他任何东西区分开来。每个特征的apply方法都使用不同数量的参数,因此无法为它们提供具有apply方法的父级。你可能接近你想要做的最接近的是:

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
  }
}

但这是疯狂和危险的,如果类型错误,将在运行时抛出异常,例如。

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