Próbowałem dowiedzieć się, jak napisać funkcjonalną funkcję wymiany, która działa na każdym Traversable[_]
, biorąc pod uwagę kolekcję i indeksy do zamiany. Wpadłem poniżej:Wzbogacić-Moja-Biblioteka Dla wszystkich Traversables
def swap[A, CC <% Traversable[A]](xs: CC, i: Int, j: Int): Traversable[A] = {
xs.slice(0, i) ++
xs.slice(j, j+1) ++
xs.slice(i+1, j) ++
xs.slice(i, i+1) ++
xs.slice(j+1, xs.size)
}
swap(List(1,2,3,4,5), 0, 4) // => List(5,2,3,4,1)
Chciałbym wiedzieć, jak zrobić to w sposób dorozumiany przedłużenie przesuwny, umożliwiając mi nazwać z List(1,2,3,4,5).swap(0, 4)
. Najbliższe, jakie mogłem uzyskać, to:
import language.implicitConversions
class RichTraversable[A, B <% Traversable[A]](xs: B) {
def swap(i: Int, j: Int): Traversable[A] = {
xs.slice(0, i) ++
xs.slice(j, j+1) ++
xs.slice(i+1, j) ++
xs.slice(i, i+1) ++
xs.slice(j+1, xs.size)
}
}
implicit def richTraversable[A, B <% Traversable[A]](ys: B)(implicit b: Traversable[A])
= new RichTraversable[A, B](ys)
Niestety to nie wszystko. Wywołanie List(1,2,3,4,5).swap(0, 4)
wyniki w następujący błąd:
error: No implicit view available from List[Int] => Traversable[A]
czuję musi być czegoś brakuje, lub znacznie nadmiernie komplikuje sprawę. Czy ktokolwiek wie, jak powinno to wyglądać?
Uwaga: To jest czysto akademicki, i nie jest używana w środowisku produkcyjnym w jakikolwiek sposób. Próbuję uzyskać lepszą kontrolę nad systemem typu Scala i ograniczeniami.
Po pierwsze: Woah, co to jest budowniczy, którego nigdy wcześniej nie widziałem? I drugie: tak, możemy zgodzić się nazwać to od teraz =) – KChaloux
Konstruktor jest tym, co jest używane w wewnętrznych kolekcjach. Zobacz na przykład: https://github.com/scala/scala/blob/master/src/library/scala/collection/TraversableLike.scala#L237 – dhg
Hmm. Nie mogę go znaleźć, aby znaleźć CanBuildFrom lub TraversableLike. Czy brakuje mi importu? – KChaloux