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 // constructor cannot be instantiated to expected type; found : B[V] required: A[Option[U],?V1] where type ?V1 <: V (this is a 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 // This works
}
}
エラーを変更する、または解消するには、いくつかの方法があります。
特性 A (およびケース クラス 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() => ??? // constructor cannot be instantiated to expected type; found : B required: A[U]
}
}
object Test2 {
def test2[U](t: A[U]) = t match {
case B() => ??? // This works
}
def test3[U] = {
def test(t: A[U]) = t match {
case B() => ??? // This works
}
}
}
単純化すると、これはコンパイラのバグまたは制限のように見えます。または、何か不足していますか?