I am slowly teaching myself Scala type classes. Suppose I have the following example:
object Example extends App {
trait Serializer[T] {
def serialize(seq: Seq[T]): String
}
object Serializer {
def serialize[T](seq: Seq[T])(implicit serializer: Serializer[T]): Value = serializer.serialize(seq)
}
implicit object StringSerializer extends Serializer[String] {
def serialize(seq: Seq[String]): String = seq.toString()
}
implicit object IntSerializer extends Serializer[Int] {
def serialize(seq: Seq[Int]): String = seq.toString()
}
case class Data[T: Serializer](x: Seq[T], y: Seq[T], z: Seq[T]) {
val series = Data.createString(x, y, z)
}
object Data {
def createString[T : Serializer](x: Seq[T], y: Seq[T], z: Seq[T]) = {
val serialize = implicitly[Serializer[T]]
List(serialize.serialize(x), serialize.serialize(y))
}
}
val x = Seq("a", "b", "c")
val y = Seq(1, 2, 3, 4)
val z = Seq(10, 20, 30)
val data = Data(x, y, z)
println(data.series)
}
Now this fails with
could not find implicit value for evidence parameter of type Example.Serializer[Any] [error] val data = Data(x, y, z)
Can someone please guide me as to how I can make createString
method work? From my understanding because I have a Seq[Int]
and a Seq[String]
, the type [T]
will get inferred as [Any]
, which causes the issue.
However, I put a context bound based on my Serializer
type class, which I thought would make the compiler look for a String
or Int
serializer, which it fails to do. I basically want to pass in any sequence for which I have a defined serializer, so in this any combination of Seq[Int]
and Seq[String]
.
Any guidance would be much appreciated!