2014-12-11 16 views
14

consideri il seguente esempio:valori delle etichette estratto da un'istanza LabelledGeneric

import shapeless._ 

case class Foo(bar: String, baz: Boolean) 
val labl = LabelledGeneric[Foo] 

Ora, il tipo di labl è (prettified)

LabelledGeneric[Foo] { 
    type Repr = 
    FieldType[Symbol @@ String("bar"), String] :: 
    FieldType[Symbol @@ String("baz"), Boolean] :: 
    HNil 
} 

che convoglia già delle informazioni necessarie, ossia i nomi dei campi della classe case.

Quello che sto cercando è un modo per andare da labl a qualcosa sulla falsariga di

"bar" :: "baz" :: HNil 

cioè si materializzano le informazioni contenute nei tipi singleton in un valore.

È possibile? Potrei usare una macro, ma sento che finirei per riscrivere qualcosa di molto simile all'oggetto GenericMacros in forma informe, quindi mi chiedo se posso sfruttarlo direttamente.

risposta

16

È possibile ottenere le chiavi del record (come Symbol s) tramite shapeless.ops.record.Keys.

Questo

import shapeless._ 
import shapeless.ops.record._ 

case class Foo(bar: String, baz: Boolean) 
val labl = LabelledGeneric[Foo] 
val keys = Keys[labl.Repr].apply 
println(keys) 
println(keys.toList.map(_.name)) 

risultati in

'bar :: 'baz :: HNil 
List(bar, baz) : List(String) 
+4

grande, grazie! Una nota minore: nonostante ciò che sembra dal primo println, il tipo 'keys' non è un' HList' di simboli o stringhe, ma contiene anche le informazioni sui tag. Avevo bisogno di un 'HList' di stringhe pure, quindi dovevo mappare su' HList' con un 'Poly1' lungo le linee di ' oggetto toName estende Poly1 { implicit def keyToName [A] = in [Simbolo con A ] (_. nome) } ' –