estatico / generic-traits

Automatic generic derivation for traits

Version Matrix

Generic Traits

Build Status Gitter Maven Central

Automatic generic derivation for traits

Usage

For traits which are not coproducts (e.g. not part of a sealed trait/case class family), this library allows you to derive shapeless Generic and LabelledGeneric instances from accessor fields. These instances allow us to operate on our traits generically; for instance, we can automatically derive type class instances for them.

Simply importing io.estatico.generic.traits._ will bring in the implicit macro used to derive instances. See the example usage below.

scala> :paste
// Entering paste mode (ctrl-D to finish)

import io.estatico.generic.traits._

trait Foo {
  def bar: String
  def baz: Int
}

// Exiting paste mode, now interpreting.

scala> shapeless.Generic[Foo]
res0: shapeless.Generic[Foo]{type Repr = shapeless.::[String,shapeless.::[Int,shapeless.HNil]]} = $anon$1@38245121

scala> val foo = new Foo { val bar = "a" ; val baz = 1 }
foo: Foo{val bar: String; val baz: Int} = $anon$1@1f0ed694

scala> val repr = shapeless.Generic[Foo].to(foo)
repr: shapeless.::[String,shapeless.::[Int,shapeless.HNil]] = a :: 1 :: HNil

scala> val foo = shapeless.Generic[Foo].from(repr)
foo: Foo = $anon$1$$anon$2@10423297

scala> (foo.bar, foo.baz)
res1: String = (a,1)

scala> shapeless.LabelledGeneric[Foo]
res2: shapeless.LabelledGeneric[Foo]{type Repr = shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("bar")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged
[String("baz")],Int],shapeless.HNil]]} = shapeless.LabelledGeneric$$anon$1@1d3983be

scala> val repr = shapeless.LabelledGeneric[Foo].to(foo)
repr: shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("bar")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("baz")],Int],shapeless.HNil]] = a :
: 1 :: HNil

scala> val foo = shapeless.LabelledGeneric[Foo].from(repr)
foo: Foo = $anon$2$$anon$3@2a03c5d

scala> (res1.bar, res1.baz)
res3: (String, Int) = (a,1)