Say we have the following two traits:
trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar
And an implicit conversion from the second to the first:
implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
We create a Bar
and a list of integers:
val bar = new Bar {}
val stuff = List(1, 2, 3)
Now I'd expect the following to work:
bar howMany stuff
But it doesn't:
scala> bar howMany stuff
<console>:13: error: type mismatch;
found : List[Int]
required: List[A]
bar howMany stuff
^
So we go to the spec, which has this to say (emphasis in bold is mine):
Views are applied in three situations.
[Isn't relevant here.]
In a selection e.m with e of type T, if the selector m does not denote a member of T. In this case, a view v is searched which is applicable to e and whose result contains a member named m. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of T. If such a view is found, the selection e.m is converted to v(e).m.
In a selection e.m(args) with e of type T, if the selector m denotes some member(s) of T, but none of these members is applicable to the arguments args. In this case a view v is searched which is applicable to e and whose result contains a method m which is applicable to args. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of T. If such a view is found, the selection e.m is converted to v(e).m(args).
So we try the following, thinking it must be too absurd to work:
trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar { def howMany = throw new Exception("I don't do anything!") }
implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
val bar = new Bar {}
val stuff = List(1, 2, 3)
But it does (on both 2.9.2 and 2.10.0-RC2, at least):
scala> bar howMany stuff
res0: Int = 3
This leads to some really strange behavior, as for example in this workaround for this problem.
I have three (closely related) questions:
I'd also appreciate any links to previous discussions of this issue—I haven't been having much luck with Google.
For everyone's reference, this could only be a bug. The way you know that is the error message:
<console>:13: error: type mismatch;
found : List[Int]
required: List[A]
List[A] is not a real type - it is List applied to its own type parameter. That is not a type which can be required since it is not a type which can be expressed.
[Edit - it's too early, who knows what I'm talking about. Ignore the above, but you can still follow the link.]
The relevant ticket for this is https://issues.scala-lang.org/browse/SI-6472 .
This seems like a bug so my answers are:
PS. In 2.8.1 your workaround of adding the dummy method to Bar doesn't make it compile.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With