Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to make Scala canBuildFrom to build collection type from Seq to Set

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
like image 898
Xiaohe Dong Avatar asked Oct 17 '25 23:10

Xiaohe Dong


1 Answers

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.

like image 72
Vladimir Matveev Avatar answered Oct 19 '25 13:10

Vladimir Matveev