I am learning about Scala on my own and ran into this. Following on from the excellent answers at Link, suppose I have the following code:
object Example extends App {
val x = Seq(1, 2, 3)
val y = Seq("1", "2", "3")
class Or[A, B]
implicit def orA[A, B](implicit ev: A): Or[A, B] = new Or
implicit def orB[A, B](implicit ev: B): Or[A, B] = new Or
def f1[T](seq: Seq[T])(implicit ev: Or[T =:= Int, T =:= String]) = {
println(seq)
}
f1(Seq(1, 2, 3))
f1(Seq("1", "2", "3"))
}
This compiles all well and good. But now lets suppose I change the function so that it takes a List of Sequences, instead of just Sequences, and try the following:
object Example extends App {
val x = Seq(1, 2, 3)
val y = Seq("1", "2", "3")
class Or[A, B]
implicit def orA[A, B](implicit ev: A): Or[A, B] = new Or
implicit def orB[A, B](implicit ev: B): Or[A, B] = new Or
def f1[T](seq: List[Seq[T]])(implicit ev: Or[T =:= Int, T =:= String]) = {
println(seq)
}
f1(List(Seq(1, 2, 3), Seq("1", "2", "3")))
}
This however fails. The error message is:
could not find implicit value for parameter ev: conusviz.Example.Or[Any =:= Int,Any =:= String]
My question is, why is this happening? I simply wrapped something the compiler should be able to infer in another type. Is there a way to get this working?
I want to the function to take a List of Int (or Indeed AnyVal) or Strings and still work. I am just a little baffled as to why the compiler is confused. Any explanation along a coded answer would be deeply appreciated from a learning perspective.
Seq(1, 2, 3)
has type Seq[Int]
, Seq("1", "2", "3")
has type Seq[String]
. Both Seq[Int]
and Seq[String]
are subtypes of Seq[Any]
. So List(Seq(1, 2, 3), Seq("1", "2", "3"))
has type List[Seq[Any]]
.
If you want types Seq[Int]
and Seq[String]
to be preserved then you need not a List
but HList
import shapeless.{HList, HNil}
import shapeless.ops.hlist.LiftAll
def f[L <: HList](seq: L)(implicit ev: LiftAll[({type l[T] = Or[T =:= Seq[Int], T =:= Seq[String]]})#l, L]) = {
println(seq)
}
f(Seq(1, 2, 3) :: Seq("1", "2", "3") :: HNil)