无形:如何表达&lt ;: Generix.Aux的案例类类型参数

时间:2016-07-29 11:53:56

标签: scala shapeless

我有以下代码基本上遍历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)
}

1 个答案:

答案 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)
}