2017-02-21 22 views

ответ

0

Смотрите определение ???:

def ??? : Nothing = throw new NotImplementedError 

Так F является Option и B является Nothing, таким образом, ваше возвращение тип Option[Nothing].

+2

Я не уверен, что это действительно объясняет, почему 'B' считается« Ничто ». Как вы получаете от выражения '???' к типу 'Option [Nothing]' требуется еще несколько шагов. –

+0

Я думаю, что это побочный эффект того, как компилятор пытается подобрать конструкторы типов в иерархии типов между 'Any' и' Nothing'. –

+0

'F [B]' фактически 'Nothing', но' Nothing' также является 'Option [Nothing]', что, безусловно, помогает компилятору найти наименьшую верхнюю границу 'Option' для' F'. –

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] 

Таким образом, компилятор делает вывод, что ваши типы имеют нижнюю границу Ничто и верхняя . Мы можем видеть это в действии с вашим примером.

scala> :t f(Option(42), ???) 
Option[Nothing] 

И с контравариантного типа CTOR Любой выводится:

scala> trait T[-A] 
defined trait T 

scala> :t f(new T[Int]{}, ???) 
T[Any] 

Скала компилятор ищет наиболее ограничительный вариант типа, где разумность держит хорошо. Поскольку он не может найти B (на самом деле нет такой вещи, как B), он ничего не знает для инвариантных и ковариантных случаев и Any для контравариантного случая.