2013-05-11 13 views
10

Przeczytam przez Scala for the Impatient i natknąłem się na coś, co sprawiło, że podrapałem się w głowę.Zwróć typ Scala za/plon

Poniższe Zwraca String:

scala> for (c<-"Hello"; i <- 0 to 1) yield (c+i).toChar 
res68: String = HIeflmlmop 

Ale to zwraca Vector:

scala> for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar 
res72: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p) 

Tekst poprzedzający te dwa przykłady czyta ...

„Kiedy ciało pętli for zaczyna się od wydajności, a następnie pętla tworzy zbiór wartości, po jednej dla każdej iteracji ... Ten typ lo opera nazywana jest rozumieniem. Wygenerowana kolekcja jest zgodna z pierwszym generatorem.

Jeśli wygenerowany zbiór jest kompatybilny z pierwszego generatora, to dlaczego nie jest drugi przykład zwracanie typu Range, jak w poniższym przykładzie:

scala> val range = 0 to 1 
range: scala.collection.immutable.Range.Inclusive = Range(0, 1) 

Albo ja źle interpretują zupełnie co tekst oznacza, "... wygenerowana kolekcja jest kompatybilna z pierwszym generatorem."

+0

Spójrz na tej nadrzędnej [Answer] (http://stackoverflow.com/a/1716558/406435), aby uzyskać lepszy wgląd w jaki sposób to działa. I [tutaj] (http: //www.devoxx.com/display/FR13/Martin + Odersky) (począwszy od 42:40) Sam Martin Odersky wyjaśnia historię, motywację i wdrażanie kolekcji scala. – senia

Odpowiedz

4

dla zrozumienia są wykonywane serie operacji map, flatMap i filter.

Podczas korzystania map na Range, masz Vector wyjściowe:

scala> 0 to 2 map (x => x * x) 
res12: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 4) 

To dlatego Range jest bardzo prosty rodzaj kolekcji, która jest w zasadzie tylko dwa trzech liczb: początek wartość, wartość końcowa i krok. Jeśli spojrzysz na wynik powyższego mapowania, zobaczysz, że wynikowe wartości nie mogą być reprezentowane przez coś typu Range.

0

w tym for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar pojmowania, 1st generatora jest typu scala.collection.immutable.Range.Inclusive wektor wyniku wydajność jest typu scala.collection.immutable.IndexedSeq [Int] jeśli sprawdzenie klasy Zakres: http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Range

to pokazuje Zakres rozciąga/wstawek z IndexedSeq. super typ IndexedSeq jest kompatybilny z podtypem Zakres.

Jeśli wynik nie może być reprezentowany przez zakres (jak wyjaśniono w poprzedniej odpowiedzi), to "wyszuka" typ super, aby przedstawić wynik.

enter image description here