I am going through the book Scala with Cats. I am trying to understand the subtleties of the scala type system. I came up with the following example:
object Example extends App {
sealed trait Serializer[T] {
def serialize(seq: List[T]): String
}
implicit object StringSerializer extends Serializer[String] {
def serialize(seq: List[String]): String = seq.toString()
}
implicit object IntSerializer extends Serializer[Int] {
def serialize(seq: List[Int]): String = seq.toString()
}
def f1[T0 : Serializer](x: List[List[T0]])(implicit s0: Serializer[T0]): List[String] = {
x.map(lst => s0.serialize(lst))
}
// some dummy data
val col1 = List("a", "b", "c", "d", "e")
val col2 = List(12, 200, 80900, 201200, 124420000)
val col3 = List(121, 12121, 71240000, 44356, 845)
val data = List(col1, col2, col3)
f1(data)
}
Now this does not compile, the following error comes up:
could not find implicit value for evidence parameter of type Example.Serializer[Any]
Now I understand why this happens; it is due to my function f1. Because I have a List[Int] and List[String] passed in to the function, the common parent type is Any. So the Type info gets erased, which passes into serializer.
However, given I have put a context bound, shouldn't the compiler first look for the implicit definitons before this takes place? Clearly it does not so my understanding is incorrect. What is the Scala way of getting round this problem.
Any explanations will be greatly appreciated!