Skip to content

Instantly share code, notes, and snippets.

@milessabin
Last active March 13, 2023 20:27
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save milessabin/fbd9da3361611b91da17 to your computer and use it in GitHub Desktop.
Save milessabin/fbd9da3361611b91da17 to your computer and use it in GitHub Desktop.
Convert (small enough) case classes to and from tuples using shapeless ...
import shapeless._
import ops.hlist.Tupler
trait TupleGeneric[C <: Product] extends Serializable {
type Repr <: Product
def to(t : C) : Repr
def from(r : Repr) : C
}
object TupleGeneric {
type Aux[C <: Product, R] = TupleGeneric[C] { type Repr = R }
def apply[C <: Product](implicit tgc: TupleGeneric[C]): Aux[C, tgc.Repr] = tgc
implicit def mkTG[C <: Product, L <: HList, R <: Product]
(implicit cGen: Generic.Aux[C, L], tup: Tupler.Aux[L, R], tGen: Generic.Aux[R, L]): Aux[C, R] =
new TupleGeneric[C] {
type Repr = R
def to(t : C) : Repr = cGen.to(t).tupled
def from(r : Repr) : C = cGen.from(tGen.to(r))
}
}
/// Repl session ...
scala> case class Person(name: String, age: Int)
defined class Person
scala> val gen = TupleGeneric[Person]
gen: TupleGeneric[Person]{type Repr = (String, Int)} = TupleGeneric$$anon$3@40fa23ce
scala> val mary = Person("Mary", 37)
mary: Person = Person(Mary,37)
scala> gen.to(mary)
res0: gen.Repr = (Mary,37)
scala> res0._1
res1: String = Mary
scala> res0._2
res2: Int = 37
scala> gen.from(("Fred", 23))
res3: Person = Person(Fred,23)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment