Why is implicit conversion from Long to RichLong not applied where a supertype of RichLong is expected?

StackOverflow https://stackoverflow.com/questions/3586044

  •  01-10-2019
  •  | 
  •  

Question

Scala 2.8 spec says in section 7.3 (highlighting is mine):

Implicit parameters and methods can also define implicit conversions called views. A view from type S to type T is defined by an implicit value which has function type S=>T or (=>S)=>T or by a method convertible to a value of that type. Views are applied in two situations.

  1. If an expression e is of type T, and T does not conform to the expression’s expected type pt. In this case an implicit v is searched which is applicable to e and whose result type conforms to pt. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of T => pt. If such a view is found, the expression e is converted to v(e).

[...]

given the above and the following facts:

  1. Long is not a subtype of java.lang.Comparable[Long], i.e. does not conform to type T where T <: java.lang.Comaparable[Long]
  2. Predef contains implicit def longWrapper (x: Long) : RichLong
  3. RichLong is a subtype of java.lang.Comparable[Long], i.e. conforms to type T where T <: java.lang.Comaparable[Long]

I would expect the implicit conversion to be applied where Long is encountered and a subtype of java.lang.Comparable[Long] is expected. However:

scala> def test[T <: java.lang.Comparable[Long]](c: T) = println(c)
test: [T <: java.lang.Comparable[Long]](c: T)Unit

scala> test(12L)
<console>:7: error: inferred type arguments [Long] do not conform to method test's type parameter bounds [T <: java.lang
.Comparable[Long]]
       test(12L)
       ^

The result is as expected if the value is converted explicitly:

scala> test(longWrapper(12L))
12

Why isn't the conversion function applied implicitly?

Was it helpful?

Solution

You need to use a view-bound (<%) to have compiler look for and apply the implicit conversion.

scala> def test[T <% java.lang.Comparable[Long]](c: T) = println(c)
test: [T](c: T)(implicit evidence$1: (T) => java.lang.Comparable[Long])Unit

scala> test(12L)
12

You can read more about view-bound on this page (Ctrl+F for "view bound").

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top