理解Scala GADT支持的限制
理解Scala GADT支持的限制
对于Test.test中的错误似乎是不合理的:
sealed trait A[-K, +V] case class B[+V]() extends A[Option[Unit], V] case class Test[U]() { def test[V](t: A[Option[U], V]) = t match { case B() => null // 构造函数无法实例化到期望的类型;找到:B[V];要求:A[Option[U],?V1],其中类型?V1 <: V(这是一个GADT skolem) } def test2[V](t: A[Option[U], V]) = Test2.test2(t) } object Test2 { def test2[U, V](t: A[Option[U], V]) = t match { case B() => null // 这个可以工作 } }
有几种方法可以使错误改变或消失:
如果我们在trait A(和case class B)上删除V参数,那么错误中的'GADT-skolem'部分就会消失,但'构造函数无法实例化'部分仍然存在。
如果我们将Test类的U参数移到Test.test方法中,错误就会消失。为什么?(类似地,Test2.test2中没有错误)
下面的链接也指出了这个问题,但我不理解提供的解释。http://lambdalog.seanseefried.com/tags/GADTs.html
这是编译器的错误吗?(2.10.2-RC2)
感谢您对此事的任何澄清帮助。
2014/08/05:我已经设法进一步简化了代码,并提供了另一个例子,在该例子中,U在立即函数之外绑定而不会导致编译错误。我在2.11.2中仍然观察到这个错误。
sealed trait A[U] case class B() extends A[Unit] case class Test[U]() { def test(t: A[U]) = t match { case B() => ??? // 构造函数无法实例化到期望的类型;找到:B;要求:A[U] } } object Test2 { def test2[U](t: A[U]) = t match { case B() => ??? // 这个可以工作 } def test3[U] = { def test(t: A[U]) = t match { case B() => ??? // 这个可以工作 } } }
像这样简化之后,它看起来更像是一个编译器的错误或限制。或者是我漏掉了什么吗?