2015-01-08 1 views
1

Рассмотрим следующий простой эксперимент Scala:Переопределение членов, имеющих типы Path Dependent в Scala. Объяснение необходимо с точки зрения Scala Спецификация языка

scala> trait A {class C;val c:C} 
defined trait A 

scala> object O1 extends A {val c=new C} 
defined object O1 

scala> object O2 extends A {val c=O1.c} 
<console>:9: error: overriding value c in trait A of type O2.C; 
value c has incompatible type 
     object O2 extends A {val c=O1.c} 

Согласно спецификации Scala Language (SLS 5.1.4):

Тип значения O1.c должны соответствовать к типу A.c, потому что прежний переопределяет последний.

Вопрос 1:

Где в СЛС указано правило, из которого следует, что тип O1.c действительно ли соответствует типу A.c?

Так почему же должен object O1 extends A {val c=new C} компилировать в соответствии с SLS?

Вопрос 2:

Где в СЛС указано правило, из которого следует, что тип значения O1.c не соответствует типу значения O2.c?

Другими словами, , из которого правилу SLS следует, что object O2 extends A {val c=O1.c} не следует компилировать?

Относительно: почему тип O2.c должен быть O2.C согласно SLS?

Update:

Какой тип значения O1.c и абстрактного элемента значения A.c в соответствии с SLS?

ответ

1

Тип A.c является A#C и O1.c (обновление: типа O1.C, что в СЛС является O1.type#C) действительно соответствует A#c.

Вопрос 1: внутри O1, тип C является O1.C и new C является new O1.C (см правила десигнаторов типа в пункте 3.2.3). O1.C соответствует O1.C, потому что он эквивалентен (потому что эквивалентность является конгруэнцией).

Вопрос 2: Из этого следует, потому что O1 не соответствует O2, потому что ни одно из правил в 3.5.1 или 3.5.2 не сделает O1 соответствовать O2. Таким образом, правило для типов прогнозов в 3.5.2 не применяется.

Вызов конструктора возвращает значение этого типа в соответствии с 5.1.1.

(Я действительно не думаю, что спецификация - лучший способ изучить эти вещи, лучше получить практическое представление о том, как все работает в первую очередь).

+0

Спасибо за ваш ответ!Проблема в том, что по-прежнему существует огромный разрыв между Спецификацией и почти любой другой книгой Scala. Спецификация действительно очень трудна для чтения, но в подобных случаях книга Скалы, написанная для простых смертных, кажется, не помогает. – jhegedus

+0

Где я сказал, что 'A.c' - это тип? – jhegedus

+0

SLS 3.2.2: «Проекция типа T # x ссылается на элемент типа с именем x типа T.» Так что 'A # c' недопустим в этом случае, потому что' c' не является членом типа, поэтому 'A # c' не имеет смысла в этом контексте. Может кто-нибудь прокомментировать это? – jhegedus