首页 > 解决方案 > 无形 HList 返回类型

问题描述

我正试图在我的代码中加入一些无形的东西,并且正处于一个令人尴尬的早期障碍中。在下面的示例中,似乎 HCons 将未定义的对象添加到 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
}

并得到一个错误 - type mismatch: Found B :: L, Required O。我会认为,因为Lis 本身是 an HList,所以B :: L本身应该是 an HList,因此一切都应该很好。但显然不是。

任何帮助表示赞赏!

标签: scalagenericstypeclassimplicitshapeless

解决方案


我想错误很明显

type mismatch;
 found   : B :: L
 required: O

ev.get(a) :: l有类型B :: L但是O是预期的。

我会认为,因为Lis 本身是 an HList,所以B :: L本身应该是 an HList,因此一切都应该很好。

B :: L确实是一个HList。问题是B :: L不是O

当你写签名时

def getAll[L <: HList, O <: HList](a: A, l: L): O = ???

这意味着,对于任何类型L <: HList任何类型 O <: HList,都有值a: Al: L产生一个类型的值O。我想这不是你想要的。

也许您想O根据类型返回一个类型AB. 然后可以引入一个类型参数

trait GetAll[A, B] {
  type O
  def getAll[L <: HList](a: A, l: L): O
}

或者,也许您想O根据类型返回一个类型A, B, L <: HList。然后另外你应该转移L到特质级别

trait GetAll[A, B, L <: HList] {
  type O
  def getAll(a: A, l: L): O
}

推荐阅读