2013-03-12 16 views
7
scala> val s: Seq[Class[_ <: java.lang.Enum[_]]] = Seq(classOf[java.util.concurrent.TimeUnit]) 
s: Seq[Class[_ <: java.lang.Enum[_]]] = List(class java.util.concurrent.TimeUnit) 

scala> s.flatMap(_.getEnumConstants) 
<console>:9: error: no type parameters for method flatMap: (f: Class[_ <: java.lang.Enum[_]] => scala.collection.GenTraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[Seq[Class[_ <: java.lang.Enum[_]]],B,That])That exist so that it can be applied to arguments (Class[_ <: java.lang.Enum[_]] => scala.collection.mutable.ArrayOps[_$1(in value $anonfun) with java.lang.Object] forSome { type _$1(in value $anonfun) <: java.lang.Enum[_] }) 
--- because --- 
argument expression's type is not compatible with formal parameter type; 
found : Class[_ <: java.lang.Enum[_]] => scala.collection.mutable.ArrayOps[_$1(in value $anonfun) with java.lang.Object] forSome { type _$1(in value $anonfun) <: java.lang.Enum[_] } 
required: Class[_ <: java.lang.Enum[_]] => scala.collection.GenTr...    s.flatMap(_.getEnumConstants) 

risposta

6

Non proprio la risposta precisa, ma due osservazioni - Scala 2.10 vi darà un bello errore:

scala> s.flatMap(_.getEnumConstants) 
<console>:9: error: no type parameters for method flatMap: (f: Class[_ <: Enum[_]] => scala.collection.GenTraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[Seq[Class[_ <: Enum[_]]],B,That])That exist so that it can be applied to arguments (Class[_ <: Enum[_]] => scala.collection.mutable.ArrayOps[(some other)_$1(in object $iw) with Object] forSome { type (some other)_$1(in object $iw) <: Enum[_] }) 
--- because --- 
argument expression's type is not compatible with formal parameter type; 
found : Class[_ <: Enum[_]] => scala.collection.mutable.ArrayOps[(some other)_$1(in object $iw) with Object] forSome { type (some other)_$1(in object $iw) <: Enum[_] } 
required: Class[_ <: Enum[_]] => scala.collection.GenTraversableOnce[?B] 
       s.flatMap(_.getEnumConstants) 
       ^
<console>:9: error: type mismatch; 
found : Class[_ <: Enum[_]] => scala.collection.mutable.ArrayOps[(some other)_$1(in object $iw) with Object] forSome { type (some other)_$1(in object $iw) <: Enum[_] } 
required: Class[_ <: Enum[_]] => scala.collection.GenTraversableOnce[B] 
       s.flatMap(_.getEnumConstants) 
         ^
<console>:9: error: Cannot construct a collection of type That with elements of type B based on a collection of type Seq[Class[_ <: Enum[_]]]. 
       s.flatMap(_.getEnumConstants) 
       ^

E, se si divide il vostro flatMap, si arriva a vedere una versione più semplice del problema:

scala> s.map(_.getEnumConstants) 
res28: Seq[Array[_$1 with Object] forSome { type _$1 <: Enum[_] }] = List(Array(NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS), Array(RELEASE_0, RELEASE_1, RELEASE_2, RELEASE_3, RELEASE_4, RELEASE_5, RELEASE_6)) 
scala> res28.flatten 
<console>:10: error: No implicit view available from Array[_$1 with Object] forSome { type _$1 <: Enum[_] } => scala.collection.GenTraversableOnce[B]. 
       res28.flatten 
        ^

Questo è piuttosto sorprendente dal momento che si potrebbe pensare che dovrebbe essere facile per trasformare un Array in un GenTraversableOnce. Non ho tempo per scavare i dettagli al momento, ma io sottolineare che le seguenti cose sembrano funzionare:

s.flatMap(_.getEnumConstants.toSeq) 
s.flatMap(_.getEnumConstants.map(_.asInstanceOf[Enum[_]])) 

ho votare compilatore bug, a causa di this gist, che mostra alcuni molto strano Comportamento in REPL per questo semplice script

val s: Seq[Class[_ <: java.lang.Enum[_]]] = Seq(classOf[java.util.concurrent.TimeUnit], classOf[javax.lang.model.SourceVersion]) 
s.flatMap(_.getEnumConstants.toSeq) 
s.flatMap(_.getEnumConstants.toArray) 
1234 
+0

Come indicato nel mio altro commento, mi aspetto che "Predef.genericArrayOps" fornisca la conversione necessaria da "Array [TimeUnit]" a "ArrayOps [TimeUnit]", che eredita da "GenTraversableOnce [TimeUnit]" come previsto da la chiamata 'flatMap'. –

+0

Sono d'accordo, la domanda si riduce al motivo per cui non sembra attivare l'implicito (e forse se dovrebbe). – themel

+0

La mia ipotesi in questo momento è che il problema è relativo al necessario implicito 'CanBuildFrom [Seq [Class [_ <: java.lang.Enum [_]]], TimeUnit, Seq [TimeUnit]], ma al momento posso Troviamo quale file sorgente contiene i costruttori di tipi di esempi impliciti di default. Suppongo che postare al gruppo di utenti di scala solleciterebbe una risposta più informata. –

2

TimeUnit.getEnumConstants restituisce una matrice java TimeUnit[], mentre flatMap aspetta una GenTraversable

È possibile ottenere da con

scala> s.flatMap(_.getEnumConstants.toSeq) 
res4: Seq[Enum[_]] = List(NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS) 
+1

Quindi perché s.flatMap (x => Array (1,2,3)) funziona? – themel

+0

Scusa, non era chiaro stavo parlando di array java –

+0

Sono confuso, la mia semplice comprensione è che Java TimeUnit [] è lo stesso tipo di Array [TimeUnit] in Scala, quindi non ci dovrebbe essere una differenza, ma potrei sbagliarmi. – themel

Problemi correlati