Stavo cercando di capire come scrivere una funzione di scambio funzionale che funziona su qualsiasi Traversable[_]
, dato un insieme e gli indici da scambiare. Sono venuto con la seguente:Enrich-My-Library per tutti i 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)
Mi piacerebbe sapere come fare questo in un'estensione implicita di Traversable, mi permette di chiamarla con List(1,2,3,4,5).swap(0, 4)
. Il più vicino che ho potuto ottenere è stato il seguente:
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)
Sfortunatamente non è proprio così. Chiamata List(1,2,3,4,5).swap(0, 4)
risultati nel seguente errore:
error: No implicit view available from List[Int] => Traversable[A]
sento di dover essere perso qualcosa, o enormemente di complicare eccessivamente la questione. Qualcuno sa come dovrebbe essere strutturato?
Nota: Questo è puramente accademica, e non viene utilizzato in un ambiente di produzione in alcun modo. Sto cercando di gestire meglio il sistema di tipi e limiti di Scala.
Primo: Woah, cos'è questo builder che non ho mai visto prima? Secondo: Sì, possiamo concordare di chiamarlo da ora in poi =) – KChaloux
Il builder è ciò che viene utilizzato nelle raccolte interne. Vedi, ad esempio: https://github.com/scala/scala/blob/master/src/library/scala/collection/TraversableLike.scala#L237 – dhg
Hmm. Non riesco a trovare CanBuildFrom o TraversableLike. C'è un'importazione che mi manca? – KChaloux