3
votes

I am new to scala and after reading the scala tour I started working on a simple project to practice a bit.

In my project I wanted to extend the functionality of the Seq trait by making a implicit class that would wrap Seq and add some functionality on top.

My problem is something like this:

  implicit class wrapper[S[X] <: Seq[X], E](seq : S[E]) {
    def funkyFunc : S[S[E]] = {
      Seq[S[E]](seq)
    }
  }

This code won't compile because the compiler cant cast Seq[S[E]] to S[S[E]], so I tried to use casting like this:

  implicit class wrapper[S[X] <: Seq[X], E](seq : S[E]) {
    def funkyFunc : S[S[E]] = {
      Seq[S[E]](seq).asInstanceOf[S[S[E]]]
    }
  }

But now I the problem is at run time, when I try to pass a type that extends from Seq but list cant be cast into him we will get an exception.

I can't create an instance of type S[S[E]] because Seq doesn't have a contractor.

So is there a solution that I am missing that will let me get a behavior like this one:

  implicit class wrapper[S[X] <: Seq[X], E](seq : S[E]) {
    def funkyFunc : S[S[E]] = {
      S[S[E]]() :+ seq
    }
  }

Edit: I am using scala 2.13

1
If you are new to Scala this might not be the best place to start. It is probably better to get experience using the existing collection classes before trying to write your own.Tim
If you decide to go this way you'll have to reinvent CanBuildFrom-like concepts which has fortunately been removed in scala-2.13. Implicits + subtiping + type inference will never work well together.simpadjo

1 Answers

2
votes

Try

import scala.collection.Factory

implicit class wrapper[S[X] <: Seq[X], E](seq : S[E]) {
  def funkyFunc(implicit f: Factory[S[E], S[S[E]]]) : S[S[E]] = {
    Seq(seq).to(f)
  }
}

List(1, 2, 3).funkyFunc // List(List(1, 2, 3))