2015-09-24 5 views
4

Я хочу иметь класс, который принимает параметр с классом-зависимым типом, как это часто делал для методов. Однако, к моему удивлению, это не помогло:Использование зависимого от пути типа в качестве параметра класса

scala> trait Compiler { trait Config } 
defined trait Compiler 

// works fine, as expected 
scala> def f(c: Compiler)(conf: c.Config) = {} 
f: (c: Compiler)(conf: c.Config)Unit 

scala> class F(val c: Compiler)(val conf: c.Config) 
<console>:8: error: not found: value c 
     class F(val c: Compiler)(val conf: c.Config) 
             ^

Почему? И есть ли какие-нибудь обходные пути?

+0

я получил следующее ** без выделки **: ': 11: error: незаконный зависимый тип метода: параметр появляется в типе другого параметра в том же разделе или ранее класс F (val c: Compiler, val conf: c.Config) ^ ' –

+1

@KevinMeredith Ошибка без каррирования (это одинаково для методов) и кажется мне достаточно ясным, даже если бы я предпочел, чтобы это сработало. –

ответ

4

Обходной который кажется приемлемым (не может создать недопустимый F без дополнительных слепков):

class F private (val c: Compiler)(_conf: Compiler#Config) { 
    def conf = _conf.asInstanceOf[c.Config] 
} 

object F { 
    def apply(c: Compiler)(conf: c.Config) = new F(c)(conf) 
} 
2

Относительно того, почему путь в зависимости от типа не работают в классе первичного конструктора ответ дан в раздел 5.3 спецификации Scala языка:

a formal value parameter may not form part of the types of any of the parent classes or members of the class template

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

Но класс может иметь дополнительные конструкторы, которые делают возможным написать обходной путь, который не нуждается в дополнительных слепки и объекты:

class F private (val conf: Compiler#Config, val c: Compiler) { 
    def this(c: Compiler)(conf: c.Config) = this(conf, c) 
} 
Смежные вопросы