2013-03-12 13 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) 

Odpowiedz

6

nie bardzo dokładne odpowiedzi, ale dwie obserwacje - Scala 2.10 daje ładniejszy błąd:

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) 
       ^

A jeśli podzielisz swoją flatMap, można zobaczyć prostszą wersję wydania:

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 
        ^

który jest dość zaskakujące, ponieważ można by pomyśleć, że powinien on być łatwo przekształcić Array w GenTraversableOnce. Nie mam czasu, aby odkopać szczegóły w tej chwili, ale będę podkreślić, że następujące rzeczy wydają się działać:

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

zagłosuję błąd kompilatora, ponieważ this gist, który pokazuje niektóre bardzo dziwne zachowanie w REPL dla tego prostego skryptu

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

Jak wskazano w moim drugim komentarzu, spodziewałbym się, że 'Predef.genericArrayOps' zapewnia wymaganą konwersję z' Array [TimeUnit] 'na' ArrayOps [TimeUnit] ', który dziedziczy po' GenTraversableOnce [TimeUnit] 'zgodnie z oczekiwaniami wywołanie 'flatMap'. –

+0

Zgadzam się, pytanie sprowadza się do tego, dlaczego wydaje się, że nie powoduje ono implicite (a może nawet powinno). – themel

+0

Domyślam się, że problem jest związany z potrzebnym niejawnym 'CanBuildFrom [Seq [Klasa [_ <: java.lang.Enum [_]]], TimeUnit, Seq [TimeUnit]]', ale w tej chwili mogę nie można znaleźć pliku źródłowego zawierającego domyślne domyślne konstruktory typeclass. Przypuszczam, że wysyłanie wiadomości do grupy użytkowników scala spowodowałoby uzyskanie bardziej świadomej odpowiedzi. –

2

TimeUnit.getEnumConstants zwraca tablicę java TimeUnit[], natomiast flatMap oczekuje GenTraversable

Można dostać się z

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

Dlaczego więc działa s.flatMap (x => Array (1,2,3))? – themel

+0

Niestety, nie było jasne, że mówiłem o tablicach Javy –

+0

Jestem zdezorientowany, moje proste zrozumienie jest takie, że Java TimeUnit [] jest tego samego typu co Array [TimeUnit] w Scali, więc nie powinno być różnicy, ale mogę się mylić. – themel

Powiązane problemy