【发布时间】:2021-02-02 18:03:58
【问题描述】:
我有一个简单的 GADT 声明如下:
sealed trait T[A]
object T {
case class MkT[A <: String with Singleton](name: A) extends T[A]
}
现在我想编写一个方法来检查两个T 对象的单例类型参数是否相同,如果是这种情况,则以cats.evidence.Is 对象的形式返回该事实的证据。
我尝试了以下方法,但它不起作用:
import cats.evidence.Is
def checkIs[A, B](ta: T[A], tb: T[B]): Option[Is[A, B]] =
(ta, tb) match {
case (ta: T.MkT[a], tb: T.MkT[b]) if ta.name == tb.name =>
Some(Is.refl[A])
case _ => None
}
// [error] Main.scala:36:75: type mismatch;
// [error] found : cats.evidence.Is[A,A]
// [error] required: cats.evidence.Is[A,B]
如何让编译器相信这是正确的?
// 编辑:正如@Dmytro Mitin 指出的那样,进行运行时检查并在编译时说服编译器类型相同似乎是自相矛盾的。但这实际上是可能的,可以用更简单的 GADT 来证明:
sealed trait SI[A]
object SI {
case object S extends SI[String]
case object I extends SI[Int]
}
def checkInt[A](si: SI[A]): Option[Is[A, Int]] =
si match {
case SI.I => Some(Is.refl[Int])
case _ => None
}
【问题讨论】:
标签: scala scala-cats gadt singleton-type