假设:
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]
答案 0 :(得分:1)
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]
因此,编译器推断您的类型具有Nothing的下限和Any的上限。我们可以通过您的示例看到这一点。
scala> :t f(Option(42), ???)
Option[Nothing]
使用逆变型ctor Any推断:
scala> trait T[-A]
defined trait T
scala> :t f(new T[Int]{}, ???)
T[Any]
scala编译器会查找声音保持良好的类型最严格的版本。因为它找不到B(实际上没有B这样的东西)它对于不变和协变的情况推断没有什么,而对于逆变情况则是Any。
答案 1 :(得分:0)
见???:
的定义def ??? : Nothing = throw new NotImplementedError
因此F
为Option
而B
为Nothing
,因此您的返回类型为Option[Nothing]
。