Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning same collection type, differently parameterised

Daniel Sobral showed how we can create a method that returns the same collection type upon which it was called in his answer to this question: Returning original collection type in generic method

Is it possible to do the same for a method that uses a mapping to return a differently-parameterized version of the same collection type?

For example

def foo[A](xs: GenTraversable[A]) = xs map (_.toString)

foo( List(1, 2, 3) ) returns res: GenTraversable[String] = List(1, 2, 3)

Can this be adapted so that

foo( Set(1, 2, 3) ) returns a Set[String]

foo( List(1, 2, 3) ) returns a List[String]

foo( Vector(1, 2, 3) ) returns a Vector[String]

like image 941
Luigi Plinge Avatar asked Feb 22 '23 01:02

Luigi Plinge


1 Answers

Extending Daniel's answer to the linked question:

def foo[A,T[X] <: TraversableLike[X,T[X]]](xs: T[A])(implicit cbf: CanBuildFrom[T[A],String,T[String]]):  T[String] = xs.map(_.toString)

Note that the map method defined in TraversableLike takes an implicit CanBuildFrom parameter. This is used to create a builder for the desired collection type so it has to be parameterized the way it is in the code (i.e., based on a collection of type T[A], build a T[String] from String elements).

like image 157
Moritz Avatar answered Mar 06 '23 04:03

Moritz