2015-09-29 10 views
10

Ho il codice successivoShapeless definire l'obiettivo per la base tratto

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

voglio definire l'obiettivo comune per tutti gerarchia di classi:

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

ma ottengo l'errore: could not find implicit value for parameter mkLens: shapeless.MkFieldLens[A,Symbol with shapeless.tag.Tagged[String("id")]]

è è possibile definire l'obiettivo per tutti i bambini di trait A?

+0

È necessario fornire un MkFieldLens [A, K] implicito. Il problema è che non so come specificare K (Symbol with shapeless.tag.Tagged [String ("id")]). Qualcuno ha risolto questo? –

risposta

2

shapeless non fornisce una conversione implicita da A a Record. È possibile definire LabelledGeneric[A] per la conversione del tipo di record corrispondente:

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 
+0

wow, molte grazie! – lito

Problemi correlati