2014-05-20 6 views
5

Perché questo può essere compilato con parametri di tipo:errore di compilazione quando mescolo impliciti, parametri di tipo e niente

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

Se rimuovo loro, allora si compila. Cosa non sto capendo e, cosa più importante, cosa posso fare per risolverlo.

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() 
} 

(I parametri di tipo in questo esempio non fare nulla, ma nel vero e proprio caso d'uso mondo che avere più parametri di tipo, e alcuni possono essere niente e alcuni non lo sono).

+2

A quanto pare, l'impostazione del parametro di tipo a 'Nothing' è direttamente ciò che sta causando il problema: entrambi nudi 'A (" coldplay "). Explode()' (che è, in effetti, 'A [Nothing]') e qualsiasi altro tipo specificato, ad esempio 'A [String] (" coldplay "). Explode()' funziona bene Per quanto riguarda il "perché", aspetterò che qualcun altro risponda, semplicemente perché non lo so ... :) –

+0

Sì, io uso Nulla nel caso di uso del mondo reale e questo è quando ha iniziato a far esplodere. – monkjack

+0

Se si utilizza '-Xlog-implicit-conversions' e' -Xlog-implicits' è possibile ottenere maggiori informazioni. Sembra 'A (" coldplay "). Explode()' funziona perché la conversione implicita viene applicata prima di risolvere i parametri di tipo. Con 'A [Nothing] (" coldplay "). Explode()', il compilatore si rifiuta di dedurre 'Nothing' come parametro type su' B', anche se non ho idea del perché. – wingedsubmariner

risposta

4

E 'davvero non piace a dedurre Niente:

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 

Il -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() } 
+0

Ha bisogno di lavorare anche per niente e altri tipi. – monkjack

+0

Funziona per me. Basta non sbarazzarsi della conversione implicita parametrizzata - avere entrambi nello scope. Provalo. Inoltre, il primo tentativo in questa risposta mostra un'altra soluzione: 'classe A [+ E] (...)' –

+0

La mia classe era già co-variante nel codice reale, non sembrava aiutare. – monkjack

Problemi correlati