I'd like to somehow get at compile time the name of a field of a case class in a val (possibly a singleton-typed string or symbol?).
Something like the following:
import shapeless._
case class MyClass(field1: String, field2: Int)
val field1Lens = lens[MyClass] >> 'field1
// val name = field1Lens.name // it should be "field1", aka 'field1.name
I don't have to necessarily use lenses, any technique that works is fine (something with LabelledGeneric
?). I would like to have something where I can get the name of the case class field without specifying it separately. This way, if I refactor the name of the field1
member in the class, name
changes accordingly.
Of course the following doesn't work because the macro doesn't know at compile time the name of the symbol:
val name = 'field1
val field1Lens = lens[MyClass] >> name // can't possibly work
I tried lens[MyClass] >> name.narrow
but it doesn't work either
This is what I'm currently doing, and of course I don't like it:
// If I change the name of the field, compilation fails
// and I'm forced to check this line of code so I can change the string in the line below
protected val fieldNameCheck = lens[X].someField
val someField = "someField"
edit: Ok, I gave a look at gabriele's question, and by using Keys
I'm able to get an HList containing the (tagged) keys of the record.
What I need though is getting one specific field, not a list containing all of them.
I'm trying to use select
to get a particular key but I haven't succeeded so far
import shapeless._
import shapeless.syntax.singleton._
import shapeless.ops.record._
case class Foo(bar: String, baz: Boolean)
val labl = LabelledGeneric[Foo]
val keys = Keys[labl.Repr].apply
// the following doesn't work
// val bar = 'bar.narrow
// keys.select[bar.type]
// keys.get('bar)