次のコードFoo
が不変の場合は機能するのに、共変の場合は機能しないのはなぜですか? の共変バージョンは、 の呼び出しで引数に型がありますが必須Foo
であるという型エラーを生成します。に対しても同様のエラーが生成されます。useF1
Foo[T]
F1
useF2
分散注釈が から削除されたFoo
場合、コードは機能します。に対するパターン マッチF1
は、 という事実を明らかにするT = Int
ので、それx
は型を持っていFoo[Int]
ます。の引数でに変換するFoo[Int]
ために、暗黙の変換関数が使用されます。についても同様です。Foo が共変である場合、このプロセスのどの部分が異なりますか? また、その理由は?F1
useF1
F2
// 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]
、それらの間にサブタイプの関係は成り立たないため、サブタイプはこの例に影響を与えるべきではありません。