2016-12-05 3 views

ответ

8

Компилятор не имеет достаточных доказательств того, что S#T может быть использована в качестве аргумента для test в конкретном случае.

Рассмотрим hypotecical примера ослаблена лестница компилятора

trait A2 extends A{ 
    type T <: AnyRef 
} 

class A3 extends A2{ 
    override type T = Integer 

    def test(t: Integer): Unit = println(t * 2) 
} 

Так B[A2] должен принять экземпляр A3 вместе со всем, что есть <: AnyRef в то время как A3 потребности точно Integer своей собственной test реализации

Вы можете поймать бетон введите определение B, чтобы убедиться, какой тип будет использоваться

case class B[S <: A, ST](a: S {type T = ST}, t: ST) { 
    def test() = a.test(t) 
} 
+2

Но 'B [A2] (новый A3()," ")' не компилируется, хотя ... вы имели в виду, что это будет с моим кодом? Иначе ваше решение именно то, что мне нужно. – JbGi

+0

Ха, умный трюк! Я не знал, что можно использовать параметр типа на правом прицеле в уточнении. – Haspemulator

+0

@JbGi Да, я много думал о том, как продемонстрировать это с помощью собственно компиляционного примера, но scala-компилятор здесь довольно ограничительный. Так что пусть это просто воображаемый пример для воображаемого scala-подобного компилятора, который мог бы скомпилировать исходный исходный код – Odomontois

2

я мог придумать с кодировками (удален параметрами типа для упрощения):

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

def test0(a: A)(t : a.T) = a.test(t) 

abstract class B{ 
    val a: A 
    val t: a.T 
    def test = a.test(t) 
} 

// Exiting paste mode, now interpreting. 

test0: (a: A)(t: a.T)Unit 
defined class B 

этого с другой стороны, не работал с тематическими классами аргументами (ни классами по этому вопросу).

Одна из причин, ваша кодировка не будет работать:

scala> def test1(a: A)(t : A#T) = a.test(t) 
<console>:12: error: type mismatch; 
found : t.type (with underlying type A#T) 
required: a.T 
     def test1(a: A)(t : A#T) = a.test(t) 

Важной частью является required: a.T (по сравнению с A#T). Метод испытания в A не принимает каких-либо Т, оно принимает Т this.T, или, другими словами, Т, принадлежащих к одному конкретному экземпляру А.

+0

Спасибо! что помогло мне лучше понять! Итак, 'a.T' - это так называемый« зависимый от пути тип »? – JbGi

+0

Точно, это зависимый от пути тип. – pedrofurla

1

Вместо проекции типа можно использовать зависимый тип a.T:

trait A { 
    type T 
    def test(t: T): Unit 
} 

case class B[S <: A](a: S)(t : a.T) { 
    def test() = a.test(t) 
} 
Смежные вопросы