Search code examples
scalaimplicitflatten

Where is implicit function for flatten defined?


flatten is defined as:

override def flatten[B](implicit toIterableOnce: A => IterableOnce[B])

My code is:

val myList = List(1,2,3)
println(myList.map(x => List(x, 2*x)).flatten)

So if I understand it correctly, when I call flatten I need an implicit function defined somewhere and this function takes List[Int] as input and returns IterableOnce[Int].

I haven't defined any such function and code works fine, so implicit is found somewhere. How can I find where its exactly defined? I was expecting it in Predef, but seems its not there.


Solution

  • If you do

    // libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value
    import scala.reflect.runtime.universe.reify
    
    println(reify{ myList.map(x => List(x, 2*x)).flatten }.tree)
    

    you'll see

    App.this.myList.map(((x) => `package`.List.apply(x, 2.$times(x)))).flatten(Predef.$conforms)
    

    so implicit toIterableOnce: A => IterableOnce[B] is Predef.$conforms (you were right, it's in Predef)

    https://github.com/scala/scala/blob/2.13.x/src/library/scala/Predef.scala#L510

    /** An implicit of type `A => A` is available for all `A` because it can always
     *  be implemented using the identity function. This also means that an
     *  implicit of type `A => B` is always available when `A <: B`, because
     *  `(A => A) <: (A => B)`.
     */
    // $ to avoid accidental shadowing (e.g. scala/bug#7788)
    implicit def $conforms[A]: A => A = <:<.refl
    

    Indeed, List[Int] <: IterableOnce[Int]

    implicitly[List[Int] <:< IterableOnce[Int]] // compiles
    implicitly[List[Int] => IterableOnce[Int]] // compiles
    

    It's useful to know how to debug implicits:

    In scala 2 or 3, is it possible to debug implicit resolution process in runtime?