Scala: pimp of my library with overloads

Any ideas why this is not working?

implicit def listExtensions[A](xs : List[A]) = new ListExtensions(xs) class ListExtensions[A](xs : List[A]) { def foreach[B](f: (A, Int) => B) { var i = 0; for (el <- xs) { f(el, i); i += 1; } } } var a = List(1, 2, 3); a foreach { (el, i) => println(el, i) }; 

When I compile this with fsc 2.8.1, I get the following error: "Wrong number of parameters: expected = 1: a foreach {(el, i) => println (el, i)};". Am I doing something wrong, or is it simply impossible to add an overloaded method using the pimp my library trick?

PS The interesting thing is not about using foreach iteration (I know the zipWithIndex method), but rather about how overload and implicit conversions are reproduced together.

+2
source share
3 answers

The compiler never tries to use implicit conversion because the foreach method already exists in the list. More specifically, section 7.3 of the Scala language specification (http://www.scala-lang.org/docu/files/ScalaReference.pdf) states that implicit conversion is applied in two cases, the second case being relevant for an example:

In the choice of em with e of type T, if the selector m does not denote the term T.

As an aside, you can do foreach with an index using the zipWithIndex method.

 scala> val a = List("Java", "Scala", "Groovy") a: List[java.lang.String] = List(Java, Scala, Groovy) scala> a.zipWithIndex.foreach { case (el, idx) => println(el + " at index " + idx) } Java at index 0 Scala at index 1 Groovy at index 2 
+10
source

Implicit conversion will only work when trying to use a method that does not exist in the source type.

In this case, List has a foreach method, so the conversion will not be considered. But you will get an error message that does not match the expected signature.

+1
source
 (a : ListExtensions[Int]) foreach { (el, i) => println(el, i) }; 

Or change the name to foreachWithIndex

+1
source

All Articles