Come da alcuni alcuni suggerimenti nei commenti, ho guardato in CanBuildFrom, e questo è ciò che mi si avvicinò con:
import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
/** Filters `xs` to have only every nth element.
*/
def everyNth[A, It <: Iterable[A]]
(xs: It with IterableLike[A, It], n: Int, offset: Int = 0)
(implicit bf: CanBuildFrom[It, A , It]): It = {
val retval = bf()
retval ++= xs.zipWithIndex collect { case (x, i) if (i - offset) % n == 0 => x }
retval.result
}
Yay, funziona !!!
E c'è NO cast. In quanto tale, funziona anche per gli intervalli.
Tuttavia, dover iniziare con un retval vuoto e quindi utilizzare "++ =" per riempirlo sembra un po 'poco elegante, quindi se qualcuno ha una soluzione più elegante, sono tutto orecchie.
Ecco un'altra funzione generica che ho implementato che era un po 'più complicata di quella sopra perché il tipo di ritorno non è lo stesso del tipo di argomento. Cioè, L'ingresso è una sequenza di A
's, ma l'uscita è una sequenza di (A, A)
' s:
def zipWithSelf[A, It[A] <: Iterable[A]]
(xs: It[A] with IterableLike[A, It[A]])
(implicit bf: CanBuildFrom[It[A], (A, A), It[(A, A)]]): It[(A, A)] = {
val retval = bf()
if (xs.nonEmpty) {
retval ++= xs zip xs.tail
retval.result
} else retval.result
}
Ed ecco un altro:
/** Calls `f(x)` for all x in `xs` and returns an Iterable containing the indexes for
* which `f(x)` is true.
*
* The type of the returned Iterable will match the type of `xs`.
*/
def findAll[A, It[A] <: Iterable[A]]
(xs: It[A] with IterableLike[A, It[A]])
(f: A => Boolean)
(implicit bf: CanBuildFrom[It[A], Int, It[Int]]): It[Int] = {
val retval = bf()
retval ++= xs.zipWithIndex filter { p => f(p._1) } map { _._2 }
retval.result
}
io ancora non hanno alcuna comprensione profonda della i tipi "Mi piace" e CanBuildFrom
, ma ottengo l'essenza. Ed è abbastanza facile, nella maggior parte dei casi, scrivere la versione di casting di una funzione generica come prima passata, quindi aggiungere il codice CanBuildFrom
e IterableLike
per rendere la funzione più generale e completamente sicura.
Domanda simile che utilizza 'CanBuildFrom' per aggirare il problema: [Funzione che prende genericamente un tipo e restituisce lo stesso tipo] (http://stackoverflow.com/questions/10019529/function-which-generically-takes- un-tipo-e-torna-the-same-type). Non riesco a farlo funzionare con questa domanda, qualcun altro? – sschaef
Ho ottenuto CanBuildFrom per funzionare per la mia domanda e ho inserito la soluzione in una risposta. Guarda la risposta qui sotto se sei curioso. – Douglas
Bella risposta! A proposito, puoi accettare le tue risposte ... – sschaef