【发布时间】:2016-07-29 21:02:45
【问题描述】:
我有以下代码基本上遍历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]
奖金
如何通过根本不需要T 的实例来改进infer 方法?显然类型推断很好,但我确实需要以某种方式从HList[Lub] 实现List[String] 并映射一些东西。
鉴于我只关心类型,是否有可能仅通过知道要被多映射编码为HList? 的类型来派生List[String] 的具体实例
类似:
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)
}
【问题讨论】:
-
Automagicaltrait 无法为我编译:“traits cannot have type parameters with context bounds”,但你提到的错误当然也发生在抽象类中。 -
@devkat 我的错,那是原始实现中的一个类。