I'm writing a Scala implicit macro that automatically generates a type class for case classes (using quasiquote, both Scala 2.10.3 with the macro paradise compiler plugin and Scala 2.11.0-M7).
The implicit macro recursively looks up type classes for the parameter.
As long as the case class does not take type parameters or the type parameters are not used in the code generated, it works fine.
But once implicit value of <TypeClass>[<TypeParameter of case class>]
is required, compilation of the call site fails with "could not find implicit value for parameter e".
Here is the code that reproduces the issue:
trait TestTypeClass[A] {
def str(x: A): String
}
object Test {
implicit def BooleanTest = new TestTypeClass[Boolean] {
def str(x: Boolean) = x.toString
}
def CaseClassTestImpl[A: c.WeakTypeTag](c: Context): c.Expr[TestTypeClass[A]] = {
import c.universe._
val aType = weakTypeOf[A]
val TestTypeClassType = weakTypeOf[TestTypeClass[_]]
val typeName = aType.typeSymbol.name.decoded
val params = aType.declarations.collectFirst { case m: MethodSymbol if m.isPrimaryConstructor => m }.get.paramss.head
val paramTypes = aType.declarations.collectFirst { case m: MethodSymbol if m.isPrimaryConstructor => m }.get.paramss.head.map(_.typeSignature)
val paramList = for (i <- 0 until params.size) yield {
val param = params(i)
val paramType = paramTypes(i)
val paramName = param.name.decoded
q"str($param)"
}
println(paramList)
val src =
q"""
new TestTypeClass[$aType] {
def str(x: $aType) = Seq(..$paramList).mkString(",")
}
"""
c.Expr[TestTypeClass[A]](src)
}
implicit def CaseClassTest[A]: TestTypeClass[A] = macro CaseClassTestImpl[A]
def str[A: TestTypeClass](x: A) = implicitly[TestTypeClass[A]].str(x)
}
// somewhere in other module
implicitly[TestTypeClass[TestClass]] // OK.
implicitly[TestTypeClass[TestClass2[Boolean]]] // Error
// could not find implicit value for parameter e: TestTypeClass[TestClass2[Boolean]]
implicitly[TestTypeClass[TestClass2[TestClass]]] // Error
// could not find implicit value for parameter e: TestTypeClass[TestClass2[TestClass]]
Is it so by design, am I doing something wrong, or is it a compiler bug?
TypeClass
type class in shapeless. See @larsr_h's article here: typelevel.org/blog/2013/06/24/deriving-instances-1.html – Miles SabinTypeClass
type class. Probably I should use it or read the implementation of shapeless. Thanks a lot, for both your comment and your greate work, shapeless! – Tomoaki Takezoe