Reputation: 1006
I have two overloaded method having following signatures -
def fun(x: Seq[String]): Future[Seq[Int]] = ???
def fun(x: Seq[(String, String)]): Future[Seq[Int]] = ???
Due to type erasure, these methods can't be overloaded and hence showing compilation error. I tried using typetags as a workaround -
def fun[t: TypeTag](values: Seq[T]): Future[Seq[Int]] = {
typeOf[T] match {
case t if t =:= typeOf[String] => ???
case t if t =:= typeOf[(String, String)] => ???
case _ => ??? // Should not come here
}
}
There are two problems with this approach that I am facing -
Should not come here
case ?Thanks in advance.
Upvotes: 0
Views: 320
Reputation: 51658
For method overloading you can use
DummyImplicit
(see @MarioGalic's answer)
def fun(x: Seq[String]): Future[Seq[Int]] = ???
def fun(x: Seq[(String, String)])(implicit ev: DummyImplicit): Future[Seq[Int]] = ???
fun(Seq("a", "b"))
fun(Seq(("a", "b"), ("c", "d")))
trait FunTypeclass[A] {
def fun(x: A): Future[Seq[Int]]
}
object FunTypeclass {
implicit val string: FunTypeclass[Seq[String]] = x => ???
implicit val stringTuple2: FunTypeclass[Seq[(String, String)]] = x => ???
}
def fun[A](x: A)(implicit ftc: FunTypeclass[A]): Future[Seq[Int]] = ftc.fun(x)
fun(Seq("a", "b"))
fun(Seq(("a", "b"), ("c", "d")))
or
import scala.language.implicitConversions
trait FunMagnet {
def fun(): Future[Seq[Int]]
}
object FunMagnet {
implicit def fromString(x: Seq[String]): FunMagnet = () => ???
implicit def fromStringTuple2(x: Seq[(String, String)]): FunMagnet = () => ???
}
def fun(x: FunMagnet): Future[Seq[Int]] = x.fun()
fun(Seq("a", "b"))
fun(Seq(("a", "b"), ("c", "d")))
Overloading methods based on generics
Upvotes: 2
Reputation: 48420
Try DummyImplicit
approach instead of TypeTag
def fun(x: Seq[String]): Future[Seq[Int]] = ???
def fun(x: Seq[(String, String)])(implicit ev: DummyImplicit): Future[Seq[Int]] = ???
How can I use the values in the Seq ?
Note even though TypeTag
enables overcoming type erasure I do not think compiler inserts a cast automatically, so you would have manually call asInstanceOf
or equivalent
case t if t =:= typeOf[String] =>
val vs: Seq[String] = values.asInstanceOf[Seq[String]]
???
As a side note, TypeTag
requires dependency on scala-reflect.jar
(which might be a disadvantage, say, if we care about package size).
Upvotes: 3