2012-05-21 11 views
11

Me gustaría implementar un método que requiera arbitrariamente Seq[T] y devuelve Seq[T] también. Pero cuando se proporciona String también debe devolver String.Método que toma Seq [T] para devolver String en lugar de Seq [Char]

Pasando String trabajos debido a alguna conversión implícita de String a WrappedString extends IndexedSeq[Char], pero me da Seq[Char] a cambio. ¿Es posible recuperar String?

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() aplicación es irrelevante, es sólo un ejemplo.

Respuesta

15

Sí, es posible. Vas a tener que requerir una de esas elegantes 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 
} 

Esto también funciona con matrices. Bonificación: todas las líneas en su ejemplo se compilarán y funcionarán como se espera.

+0

Estoy bastante seguro de que no funcionará con matrices; no tiene ningún manifiesto definido –

+2

Funciona, porque el 'ClassManifest' necesario se proporciona implícitamente al método que entrega el' CanBuildFrom' apropiado, 'scala.Array.canBuildFrom'. –

+2

Esto debería ser más fácil con Miles ''FromRepr', supongo. –