I have a class that encloses and flatten a generic class (in order to contain a list of different generic typed instances):
trait XFun [P,V] {
def apply(args: P): V
}
class XRoute (val handler: XFun[_,_])
class XRoutes (val routes: List[XRoute])
so that when I create XRoutes, it can contain a list of XFun with different generic types:
val routes = new XRoutes (List[XRoute](new XRoute(new XFun[Int,Int] {
def apply[Int,Int](args: Int) = 0
}), new XRoute(new XFun[String, String] {
def apply[String, String](args: String) = ""
}
))
However when I try to call it, it causes issue:
def parse(str: String) : Any = {/* impl */}
val inputObj = parse(inputString)
val outputObj = routes(1).handler.apply(inputObj)
This gives error on the apply line:
Type mismatch, expected: _$1, actual: Any
Currently my only solution is to create a reflected methods from MethodSymbol
and call using reflectedMethod
, but how do I achieve this without reflection?
Note that I do not want to change XFun
to apply(Any):Any
because I wanna type enforcement on the front end (e.g. when creating XRoute object, I want to do XFun[String,String]
instead of having to do XFun[Any,Any]
).
First of all I think your trait definition has too many types and should just be:
trait XFun [P,V] {
def apply(args: P): V
}
And then you can just cast the object using asInstanceOf
:
routes(1).handler.asInstanceOf[XFun[Any,Any]].apply(inputObj)
Note that this is not type safe and will fail at runtime if you pass the wrong type of argument to an XFun
.