Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic#to, but with Field Names?

Using Generic#to, I can get the HList representation of a case class:

import shapeless._
case class F(x: Int, y: String)

scala> Generic[F].to( F(1, "foo") )
res1: shapeless.::[Int,shapeless.::[String,shapeless.HNil]] = 
    1 :: foo :: HNil

However, I'd like to get the following representation:

("x", 1) :: ("y", "foo") :: HNil

In other words, instead of just the F instance's fields' values, I'd like to get the field names, i.e. x and y, as well.

How can I get this representation?

like image 936
Kevin Meredith Avatar asked Nov 29 '25 20:11

Kevin Meredith


1 Answers

You're looking for LabelledGeneric.

In order to print the fields, you can then use the Fields type class (from the ops.record package), which can be invoked with .fields if you import also the record package.

Here's a full example

import shapeless._, record._, ops.record._
case class F(x: Int, y: String)    

scala> LabelledGeneric[F].to(F(1, "foo")).fields
res1: shapeless.::[(Symbol with shapeless.tag.Tagged[String("x")], Int),shapeless.::[(Symbol with shapeless.tag.Tagged[String("y")], String),shapeless.HNil]] = ('x,1) :: ('y,foo) :: HNil

If you also want to convert the keys to String:

object keysToString extends Poly1 {
  implicit def keyToName[A, B] = at[(Symbol with A, B)] { case (k, v) => (k.name, v) }
}

scala> LabelledGeneric[F].to(F(1, "foo")).fields.map(keysToString)
res2: shapeless.::[(String, Int),shapeless.::[(String, String),shapeless.HNil]] = (x,1) :: (y,foo) :: HNil
like image 133
Gabriele Petronella Avatar answered Dec 01 '25 10:12

Gabriele Petronella



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!