Я хотел бы создать общую версию следующего кода:
У меня есть класс дел и функция шифрования
case class Cat(name: String, age: Int, color: String)
val encrypt : String => String = _.hashCode.toString // as an example
val encryptableFields = Seq("color")
У меня есть Poly1, который будет выполнять сопоставление вmy HList
import shapeless._
import labelled._
import record._
trait enc extends Poly1 {
implicit def defaultEncrypt[K,V] = at[(K, V)] { case (k,v) =>field[K](v)}
}
object pol extends enc {
implicit def stringEncrypt[K <: Symbol] = at[(K, String)] { case (k,v) => field[K](if(encryptableFields contains k.name) encrypt(v) else v)}
}
Когда я использую его, он работает, как и ожидалось:
val cat = Cat("name", 1, "black")
val lgCat = LabelledGeneric[Cat]
val la = lgCat.to(cat)
val a = la.fields.map(pol)
lgCat.from(a)
// Cat("name", 1, "93818879")
Поскольку он работает, я думал о его создании в общем виде и инкапсуляции функциональности икласс типа, подобный:
trait Encryptor[T] {
val fields: Seq[String]
def encryptFields(source: T, encrypt: String => String): T
}
object Encryptor {
def forClass[A <: Product](f: Seq[String]) = new Encryptor[A] {
val fields: Seq[String] = f
override def encryptFields(source:A, encrypt: String => String): A = {
object pol extends enc {
implicit def stringEncrypt[K <: Symbol] = at[(K, String)] { case (k, v) => field[K](if (f contains k.name) encrypt(v) else v) }
}
val gen = LabelledGeneric[A]
val hList = gen.to(source)
val updated = hList.fields.map(pol)
gen.from(updated)
}
}
}
С этой реализацией я получаю следующую ошибку времени компиляции:
Error:could not find implicit value for parameter lgen: shapeless.LabelledGeneric[A]
val gen = LabelledGeneric[A]
Попытка решить эту проблему с передачей LabelledGeneric[A]
неявно поднимает больше вопросов.
def forClass[A <: Product, R <: HList](f: Seq[String])(implicit gen: implicit gen: LabelledGeneric.Aux[A, R]) = new Encryptor[A] { ... }
Жалуется на Error:(46, 27) could not find implicit value for parameter fields: shapeless.ops.record.Fields[gen.Repr]; val updated = hList.fields.map(pol)
При попытке пройти один:
def forClass[A <: Product, R <: HList, FOut <: HList](f: Seq[String])(
implicit gen: LabelledGeneric.Aux[A, R], fields: Fields.Aux[R, FOut])
У меня та же проблема.
Интересно, какпреодолеть эту проблему.