2013-05-30 2 views
3

Я пытаюсь использовать этот вид кода:значения абстрактных типов членов

trait Outer { 
    type Inner 

    def f(x:Inner) : Void 
} 

object test { 
    def apply(o: Outer, i : Outer#Inner) : Void = 
    o.f(i) 
} 

я получил ошибку в предпоследней строке:

type mismatch; found : i.type (with underlying type Outer#Inner) required: o.Inner

Если я изменяю применить Подпись к

def apply(o: Outer, i : o.Inner) : Void 

тогда я получил ошибку:

illegal dependent method type

Возможно ли, чтобы этот кусок кода работал?

ответ

5

Вы можете воспользоваться зависимыми от метода типами (см. Пример What are some compelling use cases for dependent method types?). Это потребует использовать 2 списка параметров:

trait Outer { 
    type Inner 
    def f(x:Inner): Unit 
} 

object test { 
    def apply(o: Outer)(i : o.Inner) { o.f(i) } 
} 
+0

Ну, это работает, огромное спасибо! Но imo o.Inner намного уродливее, чем Outer # Inner. Не могли бы вы объяснить, какой смысл использовать бывший, а не последний? Компилятор может выполнять только статические проверки, поэтому o.Inner должен быть равен o.type # Inner, который должен быть (статически) равен Outer # Inner. Я что-то упускаю? –

1

But imo o.Inner is much uglyier than Outer#Inner . Would you explain, what the point of use former instead of latter? The compiler can do only static checks so o.Inner should be equal o.type#Inner which should be (statically) equal to Outer#Inner . Am I missing something?

Вот причина. Представьте, что у вас есть

class Outer1 extends Outer { 
    type Inner = Int 

    def apply(i: Int) { ... } 
} 

class Outer2 extends Outer { 
    type Inner = String 

    def apply(i: Int) { ... } 
} 

test.apply(new Outer1, "abc") компилировать? Очевидно, нет, так как он назовет Outer1.apply(String), которого не существует. Но тогда test.apply(new Outer1, 1) не может скомпилировать (в противном случае вы вернетесь к зависимым от пути типам), и нет никакого способа использовать этот apply вообще!

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