2015-01-06 2 views
5

Вот простой эксперимент в Scala РЕПЛ:Ошибка, более высокие типы Scala: аргументы типа не соответствуют. Тип границы T являются более жесткими, чем тип T заявленное границы

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] = [email protected] 

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 Language ?

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

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

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

почему это проблема, которая 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?

+2

Обратите внимания, что вы» re shadowing 'TC' в' Test'. Использование нового имени переменной (например, 'class Test [X [T]]') делает сообщения более четкими. –

ответ

7

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

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

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

A type constructor parameter adds a nested type parameter clause to the type parameter... The above scoping restrictions are generalized to the case of nested type parameter clauses, which declare higher-order type parameters. Higher-order type parameters (the type parameters of a type parameter t) are only visible in their immediately surrounding parameter clause (possibly including clauses at a deeper nesting level) and in the bounds of 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]] 

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

+0

Большое спасибо за подробный ответ и за то, что он указал на проблему затенения. – jhegedus

+0

Мне интересно, объясняется ли эта ошибка, также где-то в http://lampwww.epfl.ch/~odersky/papers/mfcs06.pdf – jhegedus

+0

Из статьи: «Важной целью разработки« Веселой скалы »было показать, что Scala's ключевые правила проверки типов разрешимы ». Но более высокие типы типов приводят к, возможно, не завершающему типу проверки, поэтому бумага не включает типы более высокого типа, поэтому бумага не дает никакой помощи в понимании этого поведения. – jhegedus

0

Для полноты картины я привожу некоторые, возможно, соответствующие части СЛСА:

enter image description here

О соответствии конструкторов типа от СЛСА 3.5.2:

enter image description here

Смежные вопросы