2011-03-25 17 views

Odpowiedz

15

jest to skomplikowany wpływ mieszania kowariantna i zbiory niezmienne. Zestaw jest niezmienny: Set[A]. Ale Seq jest kowariancyjny: Seq[+A]. Teraz wyobraź sobie, że chcesz mieć metodę toSet w swoim Seq. Możesz spróbować toSet: Set[A]. Ale to nie zadziała, ponieważ jeśli A jest podklasą B, wówczas Seq[A] należy uznać za podklasę Seq[B]. Jednakże, Seq[A] nalega na zwrócenie Set[A], która jest podklasą 2 podklasy . Więc nasze pisanie jest zepsute.

Jeśli, z drugiej strony, możemy określić toSeq[B >: A]: Set[B] wtedy wszystko jest w porządku: jeśli obiecujemy możemy wrócić żadnych superklasę, następnie Seq[A] może powrócić Set[B] jak również Set[C] gdzie C jest nadklasą B. Seq[B] obiecał również zwrócić Set[B] lub niektóre Set[C] również, więc nie mamy żadnych wątpliwości: metoda na Seq[A] może zrobić wszystko, co może zrobić metoda na Seq[B].

Ale teraz spojrzeć na to, co biedny typer ma do czynienia z:

s.toSet[B >: I] 
.toSeq/* Type B >: I*/ 
.sortBy[C](/* some f:B => C */)(/* implicit ordering on C */) 

Nie jest sposób, aby rozwiązać ten problem - mianowicie zdecydować, że B jest I i wpisać funkcję i C odpowiednio. Ale to dość skomplikowane wyszukiwanie i to więcej niż kompilator może obsłużyć w tej chwili. Dlatego prosi o pomoc przy typie wejścia do funkcji, aby w tym momencie wiedział, B (a następnie może przekazać go z powrotem do toSet).

Ale może, jeśli chce, poradzić się w wielu płaszczyznach:

s.toSet[I].toSeq.sortBy(_.i) 
s.toSet.toSeq.sortBy[Int](_.i) 

lub można go pomóc poprzez wykazanie mu, że nie musi brać pod uwagę nowsze typy podczas wybierania najlepszego dopasowania z wcześniejszymi typami:

{ val temp = s.toSet; temp }.toSeq.sortBy(_.i) 
s.toSet match { case x => x.toSeq.sortBy(_.i) } 
+0

Rex, dzięki za to oświecenie, tego właśnie chciałem. Takie odpowiedzi nie tylko rozwiązują problem, ale także pozwalają lepiej zrozumieć, co się dzieje. Dziękuję Ci bardzo! Jaka szkoda, można tylko raz głosować: D –

0

Wygląda na coś związanego z wnioskiem o typie, nie wiem całkiem dobrze.

Ale oba następujące rade:

+0

Tak, wiem, jak przezwyciężyć problem, ale dlaczego nadal występuje w moim przypadku? To nie jest intuicyjne. –

Powiązane problemy