简体   繁体   中英

Shapeless HList return type

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 an HList , B :: L should itself be an HList 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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM