召唤 类 类型的列表
Summoning an HList of type classes
给定一个任意的 case class Cc( a: String, b: Int )
和一个类型 class trait Tc[T]
,有没有办法具体化一个简单的 HList
(或者最好是一个标记的记录)包含一个为 Cc
?
的每个参数键入 class 实例
def resolveTypeClasses[C] = ???
val resolved: Tc[String] :: Tc[Int] :: HNil = resolveTypeClasses[Cc]
由于需要解析中间值,所以很难制作单一类型参数函数Generic
。
所以从我菜鸟的角度来看,它应该是两个参数 def
,或者两个 def
的序列,每个都采用单一类型参数。第二种变体可以像这样实现:
import shapeless._
trait Tc[T]
case class Cc(a: String, b: Int)
trait ResolveTC[L] {
type Out <: HList
val out: Out
}
implicit object ResolveHNilTC extends ResolveTC[HNil] {
type Out = HNil
val out: HNil = HNil
}
implicit def resolveHListTC[X, XS <: HList](implicit tc: Tc[X], rest: ResolveTC[XS]) =
new ResolveTC[X :: XS] {
type Out = Tc[X] :: rest.Out
val out = tc :: rest.out
}
class TCResolver[C] {
def get[L <: HList](implicit gen: Generic.Aux[C, L], resolve: ResolveTC[L]): resolve.Out = resolve.out
}
def resolveTypeClasses[C] = new TCResolver[C]
implicit case object StringInst extends Tc[String]
implicit case object IntInst extends Tc[Int]
使用该实现
val resolved = resolveTypeClasses[Cc].get
将产生
StringInst :: IntInst :: HNil
给定一个任意的 case class Cc( a: String, b: Int )
和一个类型 class trait Tc[T]
,有没有办法具体化一个简单的 HList
(或者最好是一个标记的记录)包含一个为 Cc
?
def resolveTypeClasses[C] = ???
val resolved: Tc[String] :: Tc[Int] :: HNil = resolveTypeClasses[Cc]
由于需要解析中间值,所以很难制作单一类型参数函数Generic
。
所以从我菜鸟的角度来看,它应该是两个参数 def
,或者两个 def
的序列,每个都采用单一类型参数。第二种变体可以像这样实现:
import shapeless._
trait Tc[T]
case class Cc(a: String, b: Int)
trait ResolveTC[L] {
type Out <: HList
val out: Out
}
implicit object ResolveHNilTC extends ResolveTC[HNil] {
type Out = HNil
val out: HNil = HNil
}
implicit def resolveHListTC[X, XS <: HList](implicit tc: Tc[X], rest: ResolveTC[XS]) =
new ResolveTC[X :: XS] {
type Out = Tc[X] :: rest.Out
val out = tc :: rest.out
}
class TCResolver[C] {
def get[L <: HList](implicit gen: Generic.Aux[C, L], resolve: ResolveTC[L]): resolve.Out = resolve.out
}
def resolveTypeClasses[C] = new TCResolver[C]
implicit case object StringInst extends Tc[String]
implicit case object IntInst extends Tc[Int]
使用该实现
val resolved = resolveTypeClasses[Cc].get
将产生
StringInst :: IntInst :: HNil