我很确定我想做的事情可能是不可能的,反正也不是个好主意。尽管如此,这是。
我想找到一种将任何类上的任何方法转换为函数的通用方法,该函数将类的实例和方法的参数作为参数,并使用指定的参数调用实例上的方法(这是基本上方法调用如何在低级别工作:对象实例是编译器在堆栈框架上推送的隐藏参数)
示例:
鉴于
class A { def foo(param1: Type1): TypeN }
我希望有类似的东西:
def functor[X](methodName: String): (obj: X, methodParams: Types*) => TypeN
这样:
// Type (obj: A, param1: Type1) => TypeN
val fooFn = functor[A]("foo")
val res: TypeN = fooFn(new A, new Type1)
这将允许类似:
def flip[A, B, C](fn: A => B => C): B => A => C = (b: B) => (a: A) => fn(a)(b)
// Type (param1: Type1) => (obj: A) => TypeN
val fooFl = flip(fooFn.curried)
List(new A, new A).map(fooFl(new Type1) _)
这样的例子可能有用:
想象一下你有:
val divide = (i: Int) => Try(2/i).toOption
List(1, 0).map(i => divide(i).getOrElse(0))
但你想要一个可以说更清洁的人:
import OptionUtils.getOrElse
List(1, 0).map(getOrElse(0) _ compose divide)
现在,我已将getOrElse
手动定义为:
object OptionUtils {
def getOrElse[A](default: A)(option: Option[A]) = option.getOrElse(default)
}
但是希望能够为指定类中的所有(或任何给定选择)方法自动定义这样的方法。理想情况下,我会有类似的东西:
val optionUtils: Utils[Option] = Utils(Option, List("getOrElse", "or"))
optionUtils.getOrElse(None, 1) // = 1
optionUtils.getOrElseFl(1)(None) // = 1
有任何建议/意见吗?
答案 0 :(得分:1)
您可以使用Java relection(此处为scala代码)
或Scala反思:
import scala.reflect._, runtime.universe._
def functor[X: TypeTag: ClassTag, R](methodName: String)(obj: X) = {
val m = runtimeMirror(getClass.getClassLoader)
val method = typeTag[X].tpe.declaration(newTermName(methodName)).asMethod
val call = m.reflect(obj).reflectMethod(method)
(call.apply _) andThen (_.asInstanceOf[R])
}
scala> functor[Option[Int], Int]("get") _
res19: Option[Int] => (Seq[Any] => Int) = <function1>
scala> res19(Some(5))(Nil)
res20: Int = 5