如何获取 Shapeless HList 中的每个类型元素属于一个类型类的证据
How to get evidence that each type element in Shapeless HList belongs to a typeclass
我试过以下方法:
trait Evidence[H <: HList, T[_]] {}
object Evidence {
implicit def HNilEvidence[T[_]] = new Evidence[HNil, T] {}
implicit def HListEvidence[Head, Remaining <: HList, T[_]](implicit headEv: T[Head], remainingEv: Evidence[Remaining, T]) =
new Evidence[Head :: Remaining, T] {}
}
这正确地给了我一个隐含的证据,只有当所有元素都匹配一个类型类时。
但是,当尝试像这样使用它时(一个人为的例子):
def transform[A](a: A)(implicit ev: Evidence[A :: HNil, Ordering]) =
{ List(a,a).sorted }
这给出了错误
error: No implicit Ordering defined for A.
根据 Evidence[A :: HNil, Ordering]
的存在应该在那里
为什么不用 LUB
来表达 List 的内容,而只是将订购证据的请求移动到方法级别?这里的 typeclass 位具有误导性,你匹配的似乎是 type
除非我错过了明显的,而不是 type-class 或 type-family.
LUBConstraint
由于这个原因已经存在于 Shapeless 中。
class Transformer[HL <: HList, T](list: T :: HL)(
implicit val c: LUBConstraint[HL, T]
) {
def transform(obj: List[T])(
implicit ev: Ordering[T],
toList: ToList[T :: HL, T]
): List[T] = (toList(list) ::: obj).sorted(ev.reverse)
}
我也不太明白为什么需要 A
类型参数以及 A
和 LUB
之间的关系。我为您添加了一个示例,只是为了说明一点,希望它足以向您展示如何组合事物。
val list = "test3" :: "test1" :: "test2" :: HNil
val listb = List("test5", "test4", "test6")
val transformer = new Transformer(list)
transformer.transform(listb) shouldEqual List(
"test6",
"test5",
"test4",
"test3",
"test2",
"test1"
)
您不需要定义自己的 Evidence
类型 class。使用无形' ops.hlist.LiftAll
.
def transform[A](a: A)(implicit
liftAll: LiftAll.Aux[Ordering, A :: HNil, Ordering[A] :: HNil],
isHCons: IsHCons.Aux[Ordering[A] :: HNil, Ordering[A], HNil]): List[A] = {
implicit val ordering: Ordering[A] = liftAll.instances.head
List(a, a).sorted
}
我试过以下方法:
trait Evidence[H <: HList, T[_]] {}
object Evidence {
implicit def HNilEvidence[T[_]] = new Evidence[HNil, T] {}
implicit def HListEvidence[Head, Remaining <: HList, T[_]](implicit headEv: T[Head], remainingEv: Evidence[Remaining, T]) =
new Evidence[Head :: Remaining, T] {}
}
这正确地给了我一个隐含的证据,只有当所有元素都匹配一个类型类时。
但是,当尝试像这样使用它时(一个人为的例子):
def transform[A](a: A)(implicit ev: Evidence[A :: HNil, Ordering]) =
{ List(a,a).sorted }
这给出了错误
error: No implicit Ordering defined for A.
根据 Evidence[A :: HNil, Ordering]
为什么不用 LUB
来表达 List 的内容,而只是将订购证据的请求移动到方法级别?这里的 typeclass 位具有误导性,你匹配的似乎是 type
除非我错过了明显的,而不是 type-class 或 type-family.
LUBConstraint
由于这个原因已经存在于 Shapeless 中。
class Transformer[HL <: HList, T](list: T :: HL)(
implicit val c: LUBConstraint[HL, T]
) {
def transform(obj: List[T])(
implicit ev: Ordering[T],
toList: ToList[T :: HL, T]
): List[T] = (toList(list) ::: obj).sorted(ev.reverse)
}
我也不太明白为什么需要 A
类型参数以及 A
和 LUB
之间的关系。我为您添加了一个示例,只是为了说明一点,希望它足以向您展示如何组合事物。
val list = "test3" :: "test1" :: "test2" :: HNil
val listb = List("test5", "test4", "test6")
val transformer = new Transformer(list)
transformer.transform(listb) shouldEqual List(
"test6",
"test5",
"test4",
"test3",
"test2",
"test1"
)
您不需要定义自己的 Evidence
类型 class。使用无形' ops.hlist.LiftAll
.
def transform[A](a: A)(implicit
liftAll: LiftAll.Aux[Ordering, A :: HNil, Ordering[A] :: HNil],
isHCons: IsHCons.Aux[Ordering[A] :: HNil, Ordering[A], HNil]): List[A] = {
implicit val ordering: Ordering[A] = liftAll.instances.head
List(a, a).sorted
}