How to read Scala code with lots of implicits?
- by Petr Pudlák
Consider the following code fragment (adapted from http://stackoverflow.com/a/12265946/1333025):
// Using scalaz 6
import scalaz._, Scalaz._
object Example extends App {
case class Container(i: Int)
def compute(s: String): State[Container, Int] = state {
case Container(i) => (Container(i + 1), s.toInt + i)
}
val d = List("1", "2", "3")
type ContainerState[X] = State[Container, X]
println( d.traverse[ContainerState, Int](compute) ! Container(0) )
}
I understand what it does on high level. But I wanted to trace what exactly happens during the call to d.traverse at the end. Clearly, List doesn't have traverse, so it must be implicitly converted to another type that does. Even though I spent a considerable amount of time trying to find out, I wasn't very successful. First I found that there is a method in scalaz.Traversable
traverse[F[_], A, B] (f: (A) => F[B], t: T[A])(implicit arg0: Applicative[F]): F[T[B]]
but clearly this is not it (although it's most likely that "my" traverse is implemented using this one). After a lot of searching, I grepped scalaz source codes and I found scalaz.MA's method
traverse[F[_], B] (f: (A) => F[B])(implicit a: Applicative[F], t: Traverse[M]): F[M[B]]
which seems to be very close. Still I'm missing to what List is converted in my example and if it uses MA.traverse or something else.
The question is: What procedure should I follow to find out what exactly is called at d.traverse?
Having even such a simple code that is so hard analyze seems to me like a big problem. Am I missing something very simple?
How should I proceed when I want to understand such code that uses a lot of imported implicits? Is there some way to ask the compiler what implicits it used? Or is there something like Hoogle for Scala so that I can search for a method just by its name?