2012-05-21 2 views
11

Я хотел бы реализовать метод, который принимает произвольный Seq[T] и возвращает Seq[T]. Но когда предоставляется String, он также должен вернуть String.Метод, принимающий Seq [T], чтобы возвращать String, а не Seq [Char]

Передача String работы из-за какой-то неявное преобразование из String в WrappedString extends IndexedSeq[Char], но я получаю Seq[Char] взамен. Можно ли вернуть 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() реализация не имеет значения, это всего лишь пример.

ответ

15

Да, это возможно. Вы должны будете требовать один из тех причудливых CanBuildFrom с:

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 
} 

Это также будет работать с массивами. Бонус: все строки в вашем примере будут компилироваться и работать как ожидалось.

+0

Я уверен, что он не будет работать с массивами; у вас не определено явное определение –

+2

Это действительно работает, потому что необходимый «ClassManifest» предоставляется неявно методу, предоставляющему соответствующие «CanBuildFrom',' scala.Array.canBuildFrom'. –

+2

Это должно быть проще с Miles 'FromRepr', я думаю. –

Смежные вопросы