Ошибка, типы более высокого типа Scala: аргументы типа не соответствуют. границы типа T более строгие, чем объявленные границы типа T

Вот простой эксперимент в Scala REPL:

scala> trait A; trait B extends A; trait C extends B
defined trait A
defined trait B
defined trait C

scala> trait TC[T]
defined trait TC

scala> trait TC2[T <: B]
defined trait TC2

scala> class Test[TC[T]]
warning: there was one feature warning; re-run with -feature for details
defined class Test

scala> new Test[TC]
res1: Test[TC] = Test@6f195bc3

scala> new Test[TC2]



<console>:11: error: kinds of the type arguments (TC2) do not conform to the expected kinds of the type parameters (type TC) in class Test.
TC2's type parameters do not match type TC's expected parameters:
type T (in trait TC2)'s bounds <: B are stricter than type T's declared bounds >: Nothing <: Any
       val res2 =
           ^
<console>:12: error: kinds of the type arguments (TC2) do not conform to the expected kinds of the type parameters (type TC) in class Test.
TC2's type parameters do not match type TC's expected parameters:
type T (in trait TC2)'s bounds <: B are stricter than type T's declared bounds >: Nothing <: Any
              new Test[TC2]
                  ^

Вопрос 1:

Как можно объяснить эти сообщения об ошибках на основе Спецификации языка Scala?

Другими словами, какие разделы SLS объясняют эти сообщения об ошибках?

Вопрос 2: как объяснить эти сообщения об ошибках простыми терминами (не основанными на SLS)?

Формулируя предыдущий вопрос словами компилятора:

почему проблема в том, что TC2's type parameters do not match type TC's expected parameters, то есть type T (in trait TC2)'s bounds <: B are stricter than type T's declared bounds >: Nothing?

Есть ли какая-нибудь книга или статья, в которой объясняется причина этого сообщения об ошибке?

Возможно, где-то в книге Пирса TAPL?


person jhegedus    schedule 06.01.2015    source источник
comment
Обратите внимание, что вы затеняете TC в Test. Использование нового имени переменной (например, class Test[X[T]]) делает сообщения более четкими.   -  person Travis Brown    schedule 06.01.2015


Ответы (2)


Как я заметил в комментарии выше, TC в списке параметров типа Test (и в сообщении об ошибке) — это не TC, который вы определили несколькими строками ранее, — это новый параметр конструктора типа. что скрывает черту TC.

(В качестве примечания я бы настоятельно рекомендовал не затенять параметры типа. Затенение переменных на уровне значений может быть достаточно запутанным, но затенение параметров типа почти всегда является рецептом путаницы.)

Параметры конструктора типа обсуждаются в разделе 4.4 спецификации. Из этого раздела:

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

Ваш T здесь является одним из этих параметров типа более высокого порядка. Он может быть ограничен (как и любой другой параметр типа), но это не так. Вот что вызывает ошибку: вы пытаетесь предоставить конструктор типа, который ограничивает свой параметр типа (TC2) как значение параметра конструктора типа, который не разделяет ограничение (фактически не имеет никаких ограничений в все).

Чтобы получить интуитивное представление о том, почему это проблема, рассмотрите следующую черту:

trait Foo[X[_]] {
  def create[A]: X[A]
}

Это вполне разумная вещь для написания — я мог бы создать экземпляр, например, так:

object ListFoo extends Foo[List] {
  def create[A]: List[A] = Nil
}

Теперь предположим, что у меня есть конструктор типа с ограничением:

trait MyIntOptionThingy[A <: Option[Int]]

Компилятор запрещает мне создавать экземпляр Foo[MyIntOptionThingy], потому что параметр типа MyIntOptionThingy ограничен более строго, чем параметр типа X в списке параметров типа Foo. Если подумать, то это имеет смысл: как я могу определить create для любого A, когда единственными A, которые будут работать для MyIntOptionThingy, являются Some[Int], None.type и Option[Int]?

person Travis Brown    schedule 06.01.2015
comment
Большое спасибо за подробный ответ и за указание на проблему затенения. - person jhegedus; 06.01.2015
comment
Мне интересно, объясняется ли такая ошибка где-нибудь в lampwww.epfl.ch/ ~odersky/papers/mfcs06.pdf - person jhegedus; 06.01.2015
comment
Из статьи: Важной целью разработки Featherweight Scala было показать, что основные правила проверки типов Scala разрешимы. но типы более высокого типа приводят к, возможно, не завершающей проверке типов, поэтому статья не включает типы более высокого типа, поэтому статья не дает никакой помощи в понимании этого поведения. - person jhegedus; 06.01.2015
comment
@jhegedus Я думаю, что проблема здесь немного более проста: это то, как проверка соответствия границ взаимодействует с предложениями параметров вложенного типа, которые вводят типы более высокого типа. - person Travis Brown; 06.01.2015
comment
Я понимаю интуицию, основанную на вашем примере. Было бы также хорошо знать, где в SLS указано, что то, что я набрал в REPL, не должно компилироваться. В принципе это должно быть в SLS, верно? - person jhegedus; 06.01.2015
comment
Это комбинация 3.2.4 и 4.4 — я не уверен, что она станет более конкретной. - person Travis Brown; 06.01.2015
comment
Из SLS 4.3: объявление конструктора типа накладывает дополнительные ограничения на конкретные типы, которые может обозначать t. Помимо границ L и U, предложение параметра типа может налагать границы и отклонения более высокого порядка, как это регулируется соответствием конструкторов типов. - person jhegedus; 06.01.2015

Для полноты я привожу некоторые, возможно, важные части SLS:

введите здесь описание изображения

О соответствии конструкторов типов из SLS 3.5.2:

введите здесь описание изображения

person jhegedus    schedule 06.01.2015