Why doesn't the following implicit conversion work even though explicitly calling the function works?
scala> implicit def view[A, C](xs: C)(implicit ev: C <:< Iterable[A]) = new { def bar = 0 }
view: [A, C](xs: C)(implicit ev: <:<[C,scala.collection.immutable.Iterable[A]])java.lang.Object{def bar: Int}
scala> List(1) bar
<console>:147: error: Cannot prove that List[Int] <:< scala.collection.immutable.Iterable[A].
List(1) bar
^
scala> view(List(1)) bar
res37: Int = 0
I'm not really answering your question (ie, I'm answering to "how do I make this work" but not to the "why does it not work"); anyway hopefully this will help someone else make some progress towards an answer.
So... In the first case, the compiler can't infer correctly that A is an Int, given that C is a List[Int]. Honestly I'm more surprised that passing the List explicitly actually works, since the relationship between A and C is so indirect (you have a A and a C, since C is a subtype of Iterable[A] and since C is a List[Int], then A must be an Int; not a very straightforward inference...).
You can make it work by being more explicit about the relationship between C and A, like this:
scala> implicit def view[A, C[A]](xs: C[A])(implicit ev: C[A] <:< Iterable[A]) =
new { def bar = 0 }
view: [A, C[A]](xs: C[A])(implicit ev: <:<[C[A],Iterable[A]])java.lang.Object{def bar: Int}
scala> List(1) bar
res0: Int = 0
or (given that you're not using A):
scala> implicit def view[C](xs: C)(implicit ev: C <:< Iterable[_]) =
new { def bar = 0 }
scala> List(1) bar
res1: Int = 0
Simply put, as the error message suggests, it cannot infer A
. There's no information the compiler can use to infer what A
must be, so it must assume it can be anything.
You might retort that it can infer A
from C <:< Iterable[A]
, but that would turn the problem on its head: instead of using <:<
to check constraints, it would use the constraints to infer the type of A
! That logic is not sound.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.