我有以下代码基本上遍历case class
的字段并使用Poly
将它们映射到相同类型并使用ToList[HL, Out]
为简单起见,我们可以假设Poly
执行此操作:
object Schema extends Poly1 {
implicit def caseInt = at[Int](_ => "I'm an int")
implicit def caseString = at[String](_ => "Oh boy a string")
}
def infer[V1 <: Product, Out <: HList, MapperOut <: HList](v1: V1)(
implicit gen: Generic.Aux[V1, Out],
map: Mapper.Aux[Schema.type, Out, MapperOut],
to: ToList[MapperOut, String]
): List[String] = to (gen to v1 map Schema)
这一切都非常简单,适用于简单的场景:
case class Test(id: Int, text: String)
val list = infer(Test(2, "text"))
// List("I'm an int", "Oh boy a string")
现在去公共汽车不运行的地方:
class Automagical[T <: Product with Serializable : TypeTag] {
def instance: T
// The typetag bit is needed for something else
def convert: List[String] = infer(instance)
}
可悲的是,上述任何调用都失败了:
could not find implicit value for parameter gen: shapeless.Generic.Aux[T,Out]
加成
如何通过不要求infer
的实例来改进T
方法?显然类型推断很好,但我确实需要以某种方式实现List[String]
中的HList[Lub]
并映射某些内容。
鉴于我只关心类型,是否可以通过仅知道要映射编码为List[String]
HList?
的具体实例
类似的东西:
def infer[V1 <: Product, Out <: HList, MapperOut <: HList]()(
implicit gen: Generic.Aux[V1, Out],
map: Mapper.Aux[Schema.type, Out, MapperOut],
to: ToList[MapperOut, String]
): List[String] = {
// Magically build an HList with samples from its types.
// Or an alternative approach that gives the same outcome
val reifiedInstance = reify[Out]
to (reifiedInstance map Schema)
}
答案 0 :(得分:1)
为确保convert
能够访问infer
的隐式参数,必须在创建Automagical
实例时出现:
abstract class Automagical[T <: Product with Serializable : TypeTag,
Out <: HList, MapperOut <: HList]
(implicit
gen: Generic.Aux[T, Out],
map: Mapper.Aux[Schema.type, Out, MapperOut],
to: ToList[MapperOut, String]) {
def instance: T
// The typetag bit is needed for something else
def convert: List[String] = infer(instance)
}