不考虑类型参数的两种类型的等价

时间:2014-11-12 00:41:45

标签: scala macros types implicit

我想要一些隐含的证据,如下所示:

def foo[A, B](implicit ev: ???[A, B]) = ev

foo[Int, Int] //○ (compiles)
foo[Any, Int] //× (fails)
foo[Seq[Int], Seq[Int]] //○
foo[Seq[Any], Seq[Int]] //○
foo[Seq[Int], List[Int]] //×

所以两种类型必须属于同一类,但它们的类型参数并不重要(就像ClassTag一样。)你如何实现这样的功能?你使用宏吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

我的朋友在XD外面回答

sealed trait ~[A, B]
object ~ {
  implicit def a[A, B](implicit ev: A =:= B) = new ~[A, B] {}
  implicit def fa[F[_], A, B] = new ~[F[A], F[B]] {}
}

运行:

scala> implicitly[Int ~ Int]
res0: ~[Int,Int] = $tilde$$anon$1@574ae207

scala> implicitly[Int ~ Any]
<console>:10: error: could not find implicit value for parameter e: ~[Int,Any]
              implicitly[Int ~ Any]
                        ^

scala> implicitly[Seq[Int] ~ Seq[Any]]
res2: ~[Seq[Int],Seq[Any]] = $tilde$$anon$2@27dc1857

scala> implicitly[Seq[Int] ~ Seq[Int]]
res3: ~[Seq[Int],Seq[Int]] = $tilde$$anon$2@69c33436

scala> implicitly[Seq[Int] ~ List[Int]]
<console>:10: error: could not find implicit value for parameter e: ~[Seq[Int],List[Int]]
              implicitly[Seq[Int] ~ List[Int]]
                        ^