Using multiple Scala TypeClass instances in function parameters -
i created group of case classes want implement different behaviors using scala typeclass. code sample below works expected.
case class querybuilder(s: string) abstract class a() case class b() extends case class c() extends abstract class s() case class x() extends s case class y() extends s trait buildablequery[t] { def toquery(p: t): querybuilder } implicit object bquerybuilder extends buildablequery[b] { def toquery(p: b): querybuilder = { querybuilder("query of b") } } implicit object cquerybuilder extends buildablequery[c] { def toquery(p: c): querybuilder = { querybuilder("query of c") } } implicit object xquerybuilder extends buildablequery[x] { def toquery(p: x): querybuilder = { querybuilder("query of x") } } implicit object yquerybuilder extends buildablequery[y] { def toquery(p: y): querybuilder = { querybuilder("query of y") } } def toquery[a: buildablequery](value: a): querybuilder = (implicitly[buildablequery[a]]).toquery(value) println(toquery(b()).s) // query of b println(toquery(c()).s) // query of c println(toquery(x()).s) // query of x println(toquery(y()).s) // query of y
so far good. can use method toquery
of defined types.
my problem: want create function returns buildablequery
combining abstract classes a
, s
.
i tried creating new implicit object defines behavior new case class consisting of combination of a
, s
. when using in function, not compile.
case class as[i <: a, p <: s](a: i, s: p) implicit object asquerybuilder extends buildablequery[as[b, x]] { def toquery(p: as[b, x]): querybuilder = { querybuilder("query of bx") } } // not compile... // error: not find implicit value evidence parameter of type buildablequery[as[a,s]] def func(a: a, s: s): querybuilder = toquery(as(a,s)) // not compile... // error: not find implicit value evidence parameter of type buildablequery[as[i,p]] def func2[i <: a: buildablequery, p <: s: buildablequery](a: i, s: p): querybuilder = toquery(as(a,s))
does solution exist problem?
update
if want define as[i, p]
instances particular values of i
, p
, that's possible—you can define asquerybuilder
in question, , require instance in methods use type class:
def func(a: a, s: s)(implicit bq: buildablequery[as[a, s]]): querybuilder = toquery(as(a,s)) def func2[i <: a: buildablequery, p <: s: buildablequery](a: i, s: p)(implicit bq: buildablequery[as[i, p]] ): querybuilder = toquery(as(a, s))
now these compile if appropriate instances available.
original answer
it sounds want create instances generically, not as[b, x]
. can generic method:
implicit def asquerybuilder[i <: a, p <: s]: buildablequery[as[i, p]] = new buildablequery[as[i, p]] { def toquery(p: as[i, p]): querybuilder = { querybuilder("query of as") } }
now examples compile.
as side note, using same name (toquery
) both type class method , type class syntax method can make things little difficult. may want rename 1 e.g. syntax method available in definition of type class instance's toquery
.
Comments
Post a Comment