Ryoichiro Oka
Ryoichiro Oka

Reputation: 1997

Equivalence of two types without consideing type parameters

I want some implicit evidence that appears as follows:

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]] //×

So two types must be of the same class, but their type parameters don't matter (just like ClassTag.) How do you implement such function? Do you use macro?

Thank you!

Upvotes: 0

Views: 81

Answers (1)

Ryoichiro Oka
Ryoichiro Oka

Reputation: 1997

My friend answered outside 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]] {}
}

run:

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]]
                        ^

Upvotes: 2

Related Questions