I am trying to incorporate a bit of shapeless into my code and am falling at an embarassingly early hurdle. In the example below, it seems that HCons-ing an undefined object to an HNil:
trait HasValue[A, B] {
def get(a: A): B
def getAll[L <: HList, O <: HList](a: A)(implicit ga: GetAll[A, L]): O = ga.getAll(a, HNil)
}
trait GetAll[A, B] {
def getAll[L <: HList, O <: HList](a: A, l: L): O
}
implicit def getAllIfHasValue[A, B](implicit ev: HasValue[A, B]) = new GetAll[A, B] {
def getAll[L <: HList, O <: HList](a: A, l: L): O = ev.get(a) :: l
}
and getting an error - type mismatch: Found B :: L, Required O
.
I would have thought that, since L
is itself an HList
, B :: L
should itself be an HList
and therefore all should be well. But obviously not.
Any help appreciated!
I guess the error is pretty clear
type mismatch;
found : B :: L
required: O
ev.get(a) :: l
has type B :: L
but O
is expected.
I would have thought that, since
L
is itself anHList
,B :: L
should itself be anHList
and therefore all should be well.
B :: L
is an HList
, indeed. The problem is that B :: L
is not O
.
And when you write the signature
def getAll[L <: HList, O <: HList](a: A, l: L): O = ???
this means, for any type L <: HList
and any type O <: HList
, having values a: A
and l: L
produce a value of type O
. I guess that's not what you wanted.
Maybe you wanted to return a type O
depending on types A
, B
. Then you can introduce a type parameter
trait GetAll[A, B] {
type O
def getAll[L <: HList](a: A, l: L): O
}
Or maybe you wanted to return a type O
depending on types A
, B
, L <: HList
. Then additionally you should transfer L
to the trait level
trait GetAll[A, B, L <: HList] {
type O
def getAll(a: A, l: L): O
}