Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile error when I mix Implicits, type parameters and Nothing

Tags:

scala

implicit

Why does this not compile with type parameters:

error: value explode is not a member of Test.A[Nothing]

If I remove them, then it compiles. What am I not understanding, and more importantly, what can I do to fix it.

object Test extends App {

  implicit class B[E](set: A[E]) {
    def explode() = println("boom")
  }

  case class A[E](name: String)

  A[Nothing]("coldplay").explode()
}

(The type parameters in this example don't do anything, but in the real world use case I have multiple type parameters, and some can be Nothing and some are not).

like image 429
sksamuel Avatar asked Oct 01 '22 18:10

sksamuel


1 Answers

It really doesn't like to infer Nothing:

scala> implicit def a2b(a: A[Nothing]): B[Nothing] = new B(a)
<console>:17: error: type mismatch;
 found   : A[Nothing]
 required: A[T]
Note: Nothing <: T, but class A is invariant in type E.
You may wish to define E as +E instead. (SLS 4.5)
       implicit def a2b(a: A[Nothing]): B[Nothing] = new B(a)
                                                           ^

scala> implicit def a2b(a: A[Nothing]): B[Nothing] = new B[Nothing](a)
warning: there were 1 feature warning(s); re-run with -feature for details
a2b: (a: A[Nothing])B[Nothing]

scala> A[Nothing]("coldplay").explode()
boom

The -Ytyper-debug:

|    |    |    |    |    |    |    solving for (T: ?T)
|    |    |    |    |    |    |    |-- $iw.this.X.B BYVALmode-EXPRmode-FUNmode-POLYmode (silent solving: type T: method f in X) implicits disabled
|    |    |    |    |    |    |    |    [adapt] [T](set: $line3.$read.$iw.$iw.X.A[T])$line3.$read.$iw.$iw... adapted to [T](set: $line3.$read.$iw.$iw.X.A[T])$line3.$read.$iw.$iw...
|    |    |    |    |    |    |    |    \-> (set: X.A[T])X.B[T]
|    |    |    |    |    |    |    solving for (T: ?T, T: ?T)
|    |    |    |    |    |    |    \-> <error>
<console>:10: error: value explode is not a member of X.A[Nothing]
       def f() = A[Nothing]("coldplay").explode() }
like image 151
som-snytt Avatar answered Oct 04 '22 19:10

som-snytt