I'm finding that my code frequently looks a little like this:
trait Example {
def getThing1[A, O <: HList](a: A)(implicit g1: GetThing1[A] { type Out = O }): O = g1(a)
def getThing2[A, O <: HList](a: A)(implicit g2: GetThing2[A] { type Out = O }): O = g2(a)
def combineThings[T1 <: HList, T2 <: HList, O <: HList](t1: T1, t2: T2)(implicit
c: CombineThings[T1, T2] {type Out = O},
): O = c(t1, t2)
def getCombinedReversed[A, T1 <: HList, T2 <: HList, C <: HList, O <: HList](a: A)(implicit
g1: GetThing1[A] {type Out = T1},
g2: GetThing2[A] {type Out = T2},
c: CombineThings[T1, T2] {type Out = C},
r: Reverse[C] {type Out = O},
): O = r(combineThings(getThing1(a), getThing2(a)))
}
This is actually more complex than a stand-alone getCombinedReversed
method that uses implicits only and does not call the getThing1
, getThing2
or combineThings
methods:
def getCombinedReversedStandAlone[A, T1 <: HList, T2 <: HList, C <: HList, O <: HList](a: A)(implicit
g1: GetThing1[A] {type Out = T1},
g2: GetThing2[A] {type Out = T2},
c: CombineThings[T1, T2] {type Out = C},
r: Reverse[C] {type Out = O},
): O = r(c(g1(a), g2(a)))
I have no particular problem with this, but it does bloat out my code a bit, so I thought I'd check that there's no obvious solution. Obviously calling the getThing
and combineThings
methods without asserting that the correct implicit is in scope isn't possible.
Thanks for any assistance.