2012-05-21 8 views
11

Vorrei implementare il metodo che richiede un numero arbitrario di Seq[T] e restituisce anche Seq[T]. Ma quando viene fornito il numero String, è necessario restituire anche String.Metodo che esegue Seq [T] per restituire String anziché Seq [Char]

Passando String lavori a causa di qualche conversione implicita da String a WrappedString extends IndexedSeq[Char], ma ho Seq[Char] in cambio. È possibile ottenere String indietro?

val sx: Seq[Int] = firstAndLast(List(1, 2, 3, 4)) 
val s1: Seq[Char] = firstAndLast("Foo Bar") 
val s2: String = firstAndLast("Foo Bar") //incompatible types error 

def firstAndLast[T](seq: Seq[T]) = Seq(seq.head, seq.last) 

firstAndLast() attuazione è irrilevante, è solo un esempio.

risposta

15

Sì, è possibile. Dovrete richiedere una di quelle fantasia CanBuildFrom s:

import scala.collection.generic.CanBuildFrom 

def firstAndLast[CC, A, That](seq: CC)(implicit asSeq: CC => Seq[A], cbf: CanBuildFrom[CC, A, That]): That = { 
    val b = cbf(seq) 
    b.sizeHint(2) 
    b += seq.head 
    b += seq.last 
    b.result 
} 

Questo funziona anche con gli array. Bonus: tutte le righe del tuo esempio verranno compilate e funzioneranno come previsto.

+0

Sono abbastanza sicuro che non funzionerà con gli array; non hai manifest definito –

+2

Funziona, perché il necessario 'ClassManifest' viene fornito implicitamente al metodo che fornisce l'appropriato' CanBuildFrom', 'scala.Array.canBuildFrom'. –

+2

Questo dovrebbe essere più facile con "FromRepr" di Miles, immagino. –