2015-01-27 19 views
5

In Scala 2.10, data class Foo[F[_]], non posso scrivereSoppressione @unchecked avvertimento per un tipo esistenziale superiore kinded

scala> x.isInstanceOf[Foo[_]] 
<console>:10: error: _$1 takes no type parameters, expected: one 
       x.isInstanceOf[Foo[_]] 
           ^

o

scala> x.isInstanceOf[Foo[_[_]]] 
<console>:11: error: _$1 does not take type parameters 
       x.isInstanceOf[Foo[_[_]]] 
           ^

io posso scrivere x.isInstanceOf[Foo[F] forSome { type F[_]] }, che dà un avvertimento non controllato. Ho provato mettendo @unchecked annotazione in luoghi diversi, ma nessuno di loro lavoro:

scala> x.isInstanceOf[Foo[H] @unchecked forSome {type H[_]}] 
<console>:11: warning: abstract type H in type Foo[H] @unchecked forSome { type H[_] <: Any } is unchecked since it is eliminated by erasure 
       x.isInstanceOf[Foo[H] @unchecked forSome {type H[_]}] 
          ^

scala> x.isInstanceOf[Foo[H @unchecked] forSome {type H[_]}] 
<console>:11: warning: abstract type H in type Foo[H @unchecked] is unchecked since it is eliminated by erasure 
       x.isInstanceOf[Foo[H @unchecked] forSome {type H[_]}] 
          ^
<console>:11: error: kinds of the type arguments (? @unchecked) do not conform to the expected kinds of the type parameters (type F) in class Foo. 
? @unchecked's type parameters do not match type F's expected parameters: 
<none> has no type parameters, but type F has one 
       x.isInstanceOf[Foo[H @unchecked] forSome {type H[_]}] 
              ^

scala> x.isInstanceOf[Foo[H] forSome {type H[_] @unchecked}] 
<console>:1: error: `=', `>:', or `<:' expected 
     x.isInstanceOf[Foo[H] forSome {type H[_] @unchecked}] 
               ^

Esiste un modo di scrivere questo tipo esistenziale, senza un avvertimento?

+2

Penso che '@ unchecked' è solo per la corrispondenza del modello (sull'oggetto per esaustività (http://www.scala-lang.org/api/current/index.html#scala.unchecked)). Puoi comunque provare con il pattern matching, ad esempio 'obj match _: Foo [_] => ???'. –

+0

@ GáborBakos È sorprendente che 'Foo [_]' funzioni in questo contesto, ma non in 'isInstanceOf'. Se ricordo bene, ho provato la corrispondenza del pattern in precedenza, ma usando solo 'forSome', e nessuna delle varianti che ho provato ha funzionato. –

+0

@ GáborBakos Si prega di fare una risposta, quindi posso accettarlo. –

risposta

1

Con pattern matching è possibile mantenere gli avvertimenti via:

x match {case _: Foo[_] => ???} 

E 'anche un po' meno prolissa a mio parere. Nel caso nominiate la variabile case (iniziando con la lettera minuscola o con le virgolette posteriori, ovvero non _ come nell'esempio sopra prima :), avete già un asInstanceOf.

2

Tipo di indovinare:

$ scala210 -language:_ 
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.7.0_65). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> class Foo[F[_]] 
defined class Foo 

scala> (null: Any).isInstanceOf[(Foo[F] forSome { type F[_] }) @unchecked] 
res0: Boolean = false 

Il pop-up mi ha appena detto blocchi di codice non sono molto informativo.

Oh e s/guessing/experimenting.

+0

Per me funziona in Scala 2.10, ma non in 2.11.5 (sto ricevendo il solito avviso). – Kolmar

+0

@Kolmar Gabor's answer funziona anche per 2,11. –