找不到参数映射器的隐式值

问题描述

我尝试创建一个简单的基于无形的函数,将 case 类转换为字符串列表,然后我可以将其编码为 csv。

这样做的目的是在 case 类的每个成员上调用类型类 Csvencoder,然后调用方法 encode 将其更改为字符串。

类型类:

trait Csvencoder[T] {
  def encode(t: T): String
}

trait LowPriorityEncoder {
  implicit def genericEncoder[T]: Csvencoder[T] = _.toString
}

object Csvencoder extends LowPriorityEncoder {

  implicit def optionEncoder[T](
      implicit e: Csvencoder[T]
  ): Csvencoder[Option[T]] = _.fold("")(e.encode)

}

而且无形:

class CsvBuilder[Row](rows: List[Row]) {

  object csvMapper extends poly1 {

    implicit def caseEncode[V](
        implicit e: Csvencoder[V]
    ): Case.Aux[FieldType[Symbol,V],FieldType[Symbol,String]] =
      at[FieldType[Symbol,V]](s => field[Symbol](e.encode(s)))
  }

  def build[Repr <: HList,OutRepr <: HList](
      implicit labelledGeneric: LabelledGeneric.Aux[Row,Repr],mapper: Mapper.Aux[csvMapper.type,Repr,OutRepr],toMap: ToMap.Aux[OutRepr,Symbol,String]
  ): List[Map[String,String]] = {

    def transform(row: Row): Map[String,String] = {
      val formattedRows = labelledGeneric
        .to(row)
        .map(csvMapper)

      val fields = toMap(formattedRows)
        .map {
          case (k: Symbol,value: String) =>
            (k.toString -> value)
        }

      fields
    }

    rows.map(transform(_))

  }
}

当我尝试使用简单的案例类时:

final case class ProjectCsvRow(
    project: Option[String],something: Option[String],site: Option[String],state: Option[Int]
)

new CsvBuilder[ProjectCsvRow](
  List(ProjectCsvRow(Some(""),None,None))
).build

我要了

找不到参数映射器的隐含值:shapeless.ops.hlist.Mapper.Aux[stabilizer$1.csvMapper.type,OutRepr]

我想我错过了一些东西,但我真的想不通。

我已经检查过每个字段是否都有 Csvencoder 的实例。

解决方法

首先,您的 Poly 不正确。 Symbol 类型太粗糙。记录的键不仅仅是 Symbol,它们是 Symbol 的单例子类型。你应该定义

object csvMapper extends Poly1 {
  implicit def caseEncode[K <: Symbol,V](
    implicit e: CsvEncoder[V]
  ): Case.Aux[FieldType[K,V],FieldType[K,String]] =
    at[FieldType[K,V]](s => field[K](e.encode(s)))
}

其次,将 Poly 嵌套到类(而不是对象)中可能很危险(它开始依赖于 CsvBuilder 的实例,因此依赖于类型 Row)。因此将 csvMapper 移到 CsvBuilder 之外(使其路径稳定)。