为什么此类型约束对 List[Seq[AnyVal or String]] 失败

fin*_*nce 1 generics types scala implicit type-conversion

我正在自己学习 Scala 并遇到了这个问题。继Link的优秀答案之后,假设我有以下代码:

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"))
}
Run Code Online (Sandbox Code Playgroud)

这编译得很好。但是现在让我们假设我更改了函数,以便它需要一个序列列表,而不仅仅是序列,然后尝试以下操作:

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")))
}
Run Code Online (Sandbox Code Playgroud)

然而这失败了。错误信息是:

找不到参数 ev 的隐式值:conusviz.Example.Or[Any =:= Int,Any =:= String]

我的问题是,为什么会发生这种情况?我只是简单地包装了一些编译器应该能够推断出另一种类型的东西。有没有办法让这个工作?

我希望该函数采用 Int(或 Indeed AnyVal)或字符串列表,并且仍然可以工作。我对编译器为什么会感到困惑感到有些困惑。从学习的角度来看,任何对编码答案的解释都将受到深深的赞赏。

Dmy*_*tin 5

Seq(1, 2, 3)有类型Seq[Int]Seq("1", "2", "3")有类型Seq[String]。这两个Seq[Int]Seq[String]的亚型Seq[Any]。所以List(Seq(1, 2, 3), Seq("1", "2", "3"))有型List[Seq[Any]]

如果你想要类型Seq[Int]并被Seq[String]保留,那么你不需要List但是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)
Run Code Online (Sandbox Code Playgroud)