oop - Parameterizing Scala Method With Parameterized Generic Class Fails -
this:
trait simplejob[+t <: serializable, +r <: serializable] { def dostuff[t](message : t) : r } object simplejob { def get_or_create_job(name : string) = print("do stuff") def apply[t, r](name : string, message : t) : future[r] = future{"do stuff".asinstanceof[r]} def apply[s <: simplejob[t, r]](message : t) : future[r] = this(classof[s].getname, message) }
fails compile because compiler cannot resolve t, r, or s in second apply method.
note on example: i've taken out of function bodies make minimally reproducible. example fail if r not string. if interested, attempted make structure limited form of type-safe akka actor. idea simplejob subclassed , parameterized, , messages of subclass actors passed through object calls of form simplejob[actorsubclasstype].apply(message), parameter , return value type-safe. apply methods check if actor given class had been instantiated, created if had not, , pass message , return future reply. turned out not feasible number of reasons, along way realized there didn't understand scala's inhereitance system , i'm trying find out don't go down similar rabbit holes again.
if add 2 parameters this:
def apply[s <: simplejob[t, r], t, r](message : t) : future[r] = this(classof[s].getname, message)
it compiles, want able parameterize function 1 type, since resolves other types.
i'd appreciate if me understand i'm apparently misunderstanding scala's type system.
thanks in advance.
the problem in def apply[t, r, s <: simplejob[t, r]](message: t): future[r]
s
type not used in method arguments @ all, naturally not allow compiler infer concrete value of s
given arguments , vice versa. if passing instance of simplejob
method, situation opposite - compiler able infer argument types:
def apply[t, r, s <: simplejob[t, r]](sj: simplejob[t, r]) (message: t): future[r] = ???
alternatively, can use abstract type members instead of type parameters:
trait simplejob { type t <: serializable type r <: serializable def dostuff[t](message: t) : r } object simplejob { def apply[s <: simplejob](message: s#t)(implicit sct: classtag[s]): future[s#r] = future { println(sct.runtimeclass.getname); ??? } }
note cannot use classof[s]
when s
type parameter; generics in jvm not reified, therefore have use class tag machinery work around it.
Comments
Post a Comment