Бесформенный объектив для базовой характеристики

У меня есть следующий код

trait A { val id: Int } 
case class B(id: Int) extends A 
case class C(id: Int, name: String) extends A

Я хочу определить общий объектив для всей иерархии классов:

import shapeless._
import lens._ 
val idLens = lens[A] >> 'id

Но я получаю ошибку: could not find implicit value for parameter mkLens: shapeless.MkFieldLens[A,Symbol with shapeless.tag.Tagged[String("id")]]

Можно ли определить объектив для всех детей trait A?

Ответ 1

Бесформенный не обеспечивает неявное преобразование от A до Record. Вы можете определить LabelledGeneric[A], чтобы обеспечить соответствующее преобразование типа записи:

import shapeless._
import lens._
import record._
import syntax.singleton._

trait A { val id: Int }
case class B(id: Int) extends A
case class C(id: Int, name: String) extends A

implicit val lgenA = new LabelledGeneric[A] {
  type Repr = Record.`'id -> Int`.T
  def to(a: A) : Repr = ('id ->> a.id) :: HNil
  def from(r: Repr): A = new A { val id = r('id) }
}

val idLens = lens[A] >> 'id

val b = B(7)
println(idLens.get(b)) // 7