I am writing generic code for processing lists of case class instances, collecting values in each field, combining and then passing it to the library.
Using shapeless LabelledGeneric
and polymorphic functions, it looks like this:
object toNamedSingletonListOfValues extends Poly1 {
implicit def caseField[K,T] =
at[FieldType[K, T]](field => { field.key -> List[T](field) })
}
val generic = LabelledGeneric[MyClass]
val records = listOfMyClassInstances.map(generic.to)
val values = records.map(_.map(toNamedSingletonListOfValues)) // Then combining and passing
However, I need a way of getting field.key
because the library needs the parameter names.
Would you mind suggesting the solution?
You can access the key (which is known at compile-time) as a runtime value through an instance of the Witness
type class:
object toNamedSingletonListOfValues extends Poly1 {
implicit def caseField[K, T](implicit wk: Witness.Aux[K]) =
at[FieldType[K, T]](field => { wk.value -> List[T](field) })
}
No need for runtime reflection!
Found dirty hack is to make Poly look like:
import scala.reflect.runtime.universe._
object toNamedSingletonListOfValues extends Poly1 {
implicit def caseField[K: TypeTag, T] = at[FieldType[K, T]] { field =>
(typeOf[K] match { case TypeRef(_, _, args) => args }).last.toString.drop("java.lang.String(\"".size).dropRight(2) -> List[T]()
}
}
Is there a nicer solution around?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With