Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What instance of CanBuildFrom does the Scala compiler find out?

Tags:

scala

implicit

everyone . Please forgive me asking a stupid question on Scala. Though I have been programming in Scala for about 2 years, I still find it hard to understand implicit usage. Let's take an example for discussion:

Array(1,2,3,4).map(x => x) 

If you look up the scaladoc, you cant' find the method map on Array class. The reason that map can apply on Array(1,2,3,4) is that there is an implicit function implicit def intArrayOps (xs: Array[Int]): ArrayOps[Int] defined in scala.Predef.

However, there are two parameter lists, where the second one is written as implicit bf: CanBuildFrom[Array[T], B, That]). Now I wonder where the compiler finds a proper argument for type CanBuildFrom when applying map on Array(1,2,3,4).

like image 644
爱国者 Avatar asked Nov 28 '11 08:11

爱国者


2 Answers

The implicit resolution includes searching the companion object for the type of the implicit parameter as well as the companion objects for the type parameters of the implicit parameter. In the example above the signature of map is the following

def map[B, That](f: (Int) => B)(implicit bf: CanBuildFrom[Array[Int], B, That]): That

Since we have no type requirements for That we can ignore it for now. After we look in the local and container scopes and find no matching implicits, the next place to look for an implicit would be the companion object for CanBuildFrom. However it has no companion object. So we continue on and look in Array for an implicit. We find one in the form of

implicit def canBuildFrom[T](implicit m: ClassManifest[T]): CanBuildFrom[Array[_], T, Array[T]]

Since we have no type requirements and a matching implicit, "That" is forced to be of type Array[Int] and completes our typing.

like image 164
Neil Essy Avatar answered Nov 12 '22 14:11

Neil Essy


This question is partially answered with other question on StackOverflow. Let me give a try to summarize them:

The first part you need to know is where the Scala compiler looks for implicits. You can find some more detail about CanBuildFrom here.

If you have understood what is mentioned in the answers about implicits ‣you should take a look to the construction of Scala Collections. Their inheritance-hierarchy is explained here and for List here. All of them are build up with Builders. This is explained in detail in a question about breakOut.

To round up your knowledge, you should know how to pimp the Collections. Also, this is explained on StackOverflow in this question.

Please note, the best answers on StackOverflow are summarized in the Scala-Tag-Wiki.

like image 27
kiritsuku Avatar answered Nov 12 '22 15:11

kiritsuku