Scala instantiate a Concrete Class From Generic Type -
i have trait generic , goes this:
trait mytrait[t] { def dosomething(elems: seq[t]) }
i have object factory definition goes this:
object mytraitfactory { def apply[t](param1: boolean, param2: boolean): mytrait[t] = { // based on type of t, instantiate sub types } }
i have come concrete implementations example:
class mystringtrait extends mytrait[string] class myinttrait extends mytrait[int]
i need magic bit type in object factory , instantiate corresponding implementations. suggestions?
this can solved in scala using implicit typeclass. create factory trait concrete implementations each of types:
object mytraitfactory { def apply[t](param1: boolean, param2: boolean)(implicit factory: mytraitcreator[t]): mytrait[t] = { // call typeclass create method factory.create(param1, param2) } // factory trait trait mytraitcreator[t] { def create(param1: boolean, param2: boolean): mytrait[t] } // provide implicit factory object specific types: object mytraitcreator { implicit object mystringtraitcreator extends mytraitcreator[string] { override def create(param1: boolean, param2: boolean): mytrait[string] = { // create string type here new mystringtrait } } implicit object myinttraitcreator extends mytraitcreator[int] { override def create(param1: boolean, param2: boolean): mytrait[int] = { // create int type here new myinttrait } } } }
scala "hides" typeclass using implicit parameter. work, have ensure keep implicit factory objects somewhere compiler looks implicits (e.g. companion object mytraitcreator
above). pattern works without implicit
needs caller supply concrete factory on each call.
this solution includes lot of boiler plate code works statically @ compile time , not suffer type erasure. comes syntactic sugar in scala:
def apply[t: mytraitcreator](param1: boolean, param2: boolean): mytrait[t] = { // call typeclass create method implicitly[mytraitcreator[t]].factory.create(param1, param2) }
Comments
Post a Comment