3
votes

I did experiment on CanBuildFrom trait on Scala, it looks fine when I try to convert Array type to Seq type automatically, I think the reason is that we have CanBuildFrom[Array, T, Seq[T]] in the scope. However, if I try to convert Array to Set, it is not working. Further, Converting Seq to Set is not working as well. I just wonder should I define implicit into same type CanBuildFrom companion object to implement conversion ?. If it is, why scala doesnt provide it by default, is reason Set is a function ?

Here is the code which for Array to Seq

def transform[U[_]](col: Array[String])(implicit cbf: CanBuildFrom[Array[String], String, U[String]]): U[String] = {
    val builder = cbf()

    for (ele <- col) builder += ele

    builder.result()
  }

CanBuildFromSpec.transform[Seq](Array("123", "3"))

If I want to convert to Array to Set or List, it is not working

CanBuildFromSpec.transform[List](Array("123", "3")) //compilation error, cannot construct
CanBuildFromSpec.transform[Set](Array("123", "3")) //compilation error, cannot construct
1
You can supply collection.breakOut as the CanBuildFrom to your transform to allow you to build any collection (any that can holds strings at least). Or you can declare an implicit CanBuildFrom of the needed type.wingedsubmariner

1 Answers

3
votes

There is no need to reinvent a wheel - Scala collections have to[C[_]] method which allows conversion as you want it:

scala> List(1, 2, 3).to[Vector]
res0: Vector[Int] = Vector(1, 2, 3)

scala> Array(1, 2, 3).to[Seq]
res1: Seq[Int] = Vector(1, 2, 3)

scala> Seq(1, 2, 3).to[Set]
res2: Set[Int] = Set(1, 2, 3)

BTW, CanBuildFrom was introduced not for easy convertibility. It was needed in order for operations like map() or filter() to preserve original collection types.

Also Array is converted to Seq automatically not because of CanBuildFrom (that would imply that array contents are copied into the new sequence, which can be pretty inefficient), but because there is an implicit conversion from arrays to their wrappers providing Seq interface.