次のコードFooが不変の場合は機能するのに、共変の場合は機能しないのはなぜですか? の共変バージョンは、 の呼び出しで引数に型がありますが必須Fooであるという型エラーを生成します。に対しても同様のエラーが生成されます。useF1Foo[T]F1useF2
分散注釈が から削除されたFoo場合、コードは機能します。に対するパターン マッチF1は、 という事実を明らかにするT = Intので、それxは型を持っていFoo[Int]ます。の引数でに変換するFoo[Int]ために、暗黙の変換関数が使用されます。についても同様です。Foo が共変である場合、このプロセスのどの部分が異なりますか? また、その理由は?F1useF1F2
// A GADT with two constructors
sealed abstract class Foo[+T]
final case class F1() extends Foo[Int]
final case class F2() extends Foo[Unit]
object Example {
// A Foo[Int] can only be an F1
implicit def refineGADT(x : Foo[Int]) : F1 = x.asInstanceOf[F1]
// A Foo[Unit] can only be an F2
implicit def refineGADT(x : Foo[Unit]) : F2 = x.asInstanceOf[F2]
def useF1(x : F1) = ()
def useF2(x : F2) = ()
def demo[T](x : Foo[T]) = x match {
case F1() => useF1(x) // error
case F2() => useF2(x) // error
}
}
一般に、GADT はサブタイプをより複雑にしますが、この場合、考えられる具象型はFoo[Int]との 2 つだけでありFoo[Unit]、それらの間にサブタイプの関係は成り立たないため、サブタイプはこの例に影響を与えるべきではありません。