In scala language, implicit resolution is often done in compile-time and sometimes throws obfuscating error information, one famous example of such error is when shapeless G
You can debug implicits at compile time:
switch on -Xlog-implicits
try to resolve implicits manually (maybe specifying type parameters as well) and see compile errors
implicitly[...](...manually...)
use scala.reflect
println(reify { implicitly[...] }.tree)
use IDE functionality to show implicits
using macros with compiler internals you can debug implicit resolution
Is there a type-class that checks for existence of at least one implicit of a type?
create an ambiguous low priority implicit
Using the "Prolog in Scala" to find available type class instances
Finding the second matching implicit
https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/package.scala#L119-L168
If you're developing a type class don't forget to use annotations @implicitNotFound
and @implicitAmbiguous
.
You can always postpone compilation of your program till runtime. So instead of program
object App {
def main(args: Array[String]): Unit = {
println("test") // test
}
}
you can have
import scala.reflect.runtime.currentMirror
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
val toolbox = currentMirror.mkToolBox()
toolbox.eval(q"""
object App {
def main(args: Array[String]): Unit = {
println("test")
}
}
App.main(Array())
""") // test
And instead of
implicitly[Numeric[Int]]
you can have
toolbox.compile(q"""
implicitly[Numeric[Int]]
""")
or
toolbox.inferImplicitValue(
toolbox.typecheck(tq"Numeric[Int]", mode = toolbox.TYPEmode).tpe,
silent = false
)
But it's too optimistic to think that postponing program compilation till runtime you'll be able to debug implicits easier at runtime rather than at compile time. Actually postponing program compilation till runtime you add one level of indirection more i.e. make things harder to debug.