Generic method arguments in scala -
i'm not sure title describing question best let's give shot.
i have background job execution application resembles simple pipeline processing. there command objects calculation , return output, , worker receive output input , can return result object model looks this:
type output <: anyref trait command[output] { def dosomething(): output } sealed trait worker[in <: anyref, out <: result] { def work(input: in): out } case class worka() extends worker[string, longresult] { override def work(input: string): longresult = longresult(long.maxvalue) } case class workb() extends worker[long, stringresult] { override def work(input: long): stringresult = stringresult(input.tostring) } there few problems approach:
when mapping on collection of worker can't make sure worker accepts same output input.
unless i'm mapping list of command, code not compile because of type erasure - expects _$1 receives long or string (everything accepted output)
val workers = list( new worka(), new workb() ) val asimplecommand = new command[long] { override def dosomething() = 123123123l } // doesn't compile. workers.map(worker => worker.work(asimplecommand.dosomething())) i'm looking right scala mechanism disallow @ compile time. how can map on worker support output - , in case, workb
if want @ compile time can use shapeless hlists, preserving type of list way through, , using poly handle cases:
val myworkers: worka :: workb :: workb :: hnil = worka() :: workb() :: workb() :: hnil object dowork extends poly1 { implicit def caselong[a] = at[worker[long, a]] { w => w.work(asimplecommand.dosomething())} implicit def casestring = //whatever want string worker } myworkers map dowork for less safe example doesn't need shapeless, can match cases long have concrete types:
val myworkers: list[worker[_, _]] = ... myworkers collect { case wa: worka => //works case lw: worker[long, _] => //doesn't work }
Comments
Post a Comment