import shapeless._ object definition { case class Property[A](a: A) case class Embed[A](a: A) case class Hidden[A](a: A) def Prop[X] = Property[X] _ def Emb[X] = Embed[X] _ def Hid[X] = Hidden[X] _ trait Representation[A] { type Repr <: HList val repr: Repr } object Representation { type Aux[A, R] = Representation[A]{ type Repr = R } def apply[A, R <: HList](genA: Generic[A], r: R)(implicit typeAlignment: TypeAlignment[genA.Repr, R]): Aux[A, R] = new Representation[A] { type Repr = R val repr = r } } case class TypeAlignment[A, B]() object TypeAlignment { implicit def hnilTypeAlign2: TypeAlignment[HNil, HNil] = new TypeAlignment[HNil, HNil]() implicit def propertyRightAlign[A]: TypeAlignment[A, A => Property[A]] = new TypeAlignment[A, A => Property[A]]() implicit def embedRightAlign[A]: TypeAlignment[A, A => Embed[A]] = new TypeAlignment[A, A => Embed[A]]() implicit def hiddenRightAlign[A]: TypeAlignment[A, A => Hidden[A]] = new TypeAlignment[A, A => Hidden[A]]() implicit def hlistTypeAlign[A, B, TA <: HList, TB <: HList](implicit headAlignment: TypeAlignment[A, B], tailAlignment: TypeAlignment[TA, TB]): TypeAlignment[A :: TA, B :: TB] = new TypeAlignment[A :: TA, B :: TB]() } }