Why does this "Aux" pattern work for Shapeless but not for me?

99 Views Asked by At

I am trying to generate a compile-time tuple type out of a case class. I think, I am doing exactly the same thing shapeless does with generics:

class TupleProvider[T <: Product] {
  type Repr
  def provide(t: T): Repr = ???
}

object TupleProvider {
  type Aux[T <: Product, R] = TupleProvider[T] {type Repr = R}
  def apply[T <: Product](implicit tp: TupleProvider[T]): Aux[T, tp.Repr] = tp
  implicit def materialize[T, R]: Aux[T, R] = macro TypeProviderMacros.repr1[T, R]

  def instance[T <: Product, R <: Product]: Aux[T, R] = new TupleProvider[T] { type Repr = R }
}

class TypeProviderMacros(val c: whitebox.Context) {
  import c.universe._
  def repr1[T: WeakTypeTag, R: WeakTypeTag] = {
    q"TupleProvider.instance[${weakTypeOf[T]}, ${typeOf[Tuple2[String, Int]]}]"
  }
}

However, if I do something like

case class Foo(x: Int, y: String)
val p = TupleProvider[Foo]

p ends up having type TupleProvider.Aux[Foo, Nothing]

I can't figure out what specifically am I doing differently from shapless.Generic, which seems to be implemented in exactly the same way, but gives me this:

val g: Aux[Foo, Int :: String :: HNil] = Generic[Foo]

Any ideas?

0

There are 0 best solutions below