scala> def f[F[_], A, B](x: F[A], y: F[B]): F[B] = y
f: [F[_], A, B](x: F[A], y: F[B])F[B]
がどのように以下の呼び出しの出力タイプがOption[Nothing]
に評価しますか?
scala> :t f(Option(42), ???)
Option[Nothing]
scala> def f[F[_], A, B](x: F[A], y: F[B]): F[B] = y
f: [F[_], A, B](x: F[A], y: F[B])F[B]
がどのように以下の呼び出しの出力タイプがOption[Nothing]
に評価しますか?
scala> :t f(Option(42), ???)
Option[Nothing]
???の定義を参照してください:
def ??? : Nothing = throw new NotImplementedError
のでF
がOption
で、B
がNothing
あり、そのため、あなたの戻り値の型はOption[Nothing]
です。
https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#conformanceここではこの部分が特に役に立ちます。
は、あなたの関数を取る:
scala> def f[F[_], A, B >: Nothing <: Any](fa: F[A], fb: F[B]): F[B] = fb
f: [F[_], A, B](fa: F[A], fb: F[B])F[B]
コンパイラは(多かれ少なかれ)としてこれを見ている:だから
scala> def fAnnotated[F[_], A >: Nothing <: Any, B >: Nothing <: Any](fa: F[A], fb: F[B]): F[B] = fb
fAnnotated: [F[_], A, B](fa: F[A], fb: F[B])F[B]
、コンパイラがあなたのタイプは何もないと上の下限を持っていることを推測しますすべての私たちはあなたの事例でこれを実際に見ることができます。
scala> :t f(Option(42), ???)
Option[Nothing]
と反変タイプのctorとのいずれかが推測されます。
scala> trait T[-A]
defined trait T
scala> :t f(new T[Int]{}, ???)
T[Any]
Scalaのコンパイラは、健全性が良い保持しているタイプの最も制限バージョンを探します。それはBを見つけることができないので(Bのようなものは本当にありません)、それは不変の共変の場合は何も、反例の場合はAnyを推論します。
「B」が「Nothing」であると推測されている理由がこれで本当にわかりません。式 '???'から 'Option [Nothing]'型にどのように変わっていくのか、いくつかのステップが必要です。 –
これは、コンパイラがタイプのコンストラクタを 'Any'と' Nothing'の間の型階層に収める方法の副作用だと思います。 –
'F [B]'は実際には 'Nothing'ですが、' Nothing'も 'Option [Nothing]'です。これはコンパイラが 'F'の' Option'の最小限の上限を見つけるのを助けます。 –