How is Option[Something] converted to GenTraversableOnce[Something]

def getOp(i : Int) : Option[Int] = if(i==1) None else Some(i)

val list  = List(1,2,3,4)
list.flatMap(getOp) foreach println

If you see the code for flatMap of List, it has the signature -

flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[List[A], B, That]): That

It expects a function that can translate A to GenTraversableOnce[B]. But in my code I am passing a function that returns an Option. But Option does not extend GenTraversableOnce. So I am guessing some implicit is doing this? How can I find that implicit?

There is an implicit conversion from Option to Iterable defined in the Option object (https://github.com/scala/scala/blob/d350c508d8c6385182a867d49bf435d4646fa570/src/library/scala/Option.scala#L21).

You can use the reify trick to figure out what is going on:

C:\Users\marti>scala
Welcome to Scala 2.12.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_191).
Type in expressions for evaluation. Or try :help.

scala> import scala.reflect.runtime.{universe => u}
import scala.reflect.runtime.{universe=>u}

scala> u.reify { Option(1) : TraversableOnce[Int]}
res2: reflect.runtime.universe.Expr[TraversableOnce[Int]] = Expr[TraversableOnce[Int]]((Option.option2Iterable(Option.apply(1)): `package`.TraversableOnce[Int]))

in general, call scala.reflect.runtime.universe.reify{valuethatgetsconverted: TypeItGetsConvertedTo} to see what’s getting called.

3 Likes

That’s cool!

How does that one get imported?