Я борюсь с зависимыми типами в Scala 2.11.7. Вот контекст:Заводский метод с зависимым типом
trait Counter {
type T
def zero: T
def incr(t: T): T
}
object IntCounter extends Counter {
type T = Int
val zero = 0
def incr(t: Int) = t + 1
}
case class Foo(counter: Counter)
def twice(foo: Foo)(cntr: foo.counter.T): foo.counter.T =
foo.counter.incr(foo.counter.incr(cntr))
Пока все хорошо, все скомпилировано. Однако я хотел бы добавить объект, который содержит как экземпляр Foo
, так и соответствующее состояние счетчика. Например:
trait Bar {
val foo: Foo
val current: foo.counter.T
}
Определение в порядке (при условии, что я использую абстрактные vals). Но я не могу определить фабричный метод (он же умный конструктор). Все мои наивные попытки не скомпилируются. Например, определение:
def bar(f: Foo)(cntr: f.counter.T): Bar = new Bar {
val foo = f
val current = cntr
}
не может скомпилировать с ошибкой:
xxx: overriding value current in trait Bar of type this.foo.counter.T;
value current has incompatible type
val current = cntr
^
Как я могу заставить компилятор понять, что оба типа действительно то же самое? Я мог бы решить проблему с генериками вместо этого, но я предпочитаю избегать этого варианта, если это возможно.
Мне нравится ваше решение, но, как вы упомянули, оно не выражает того факта, что 'TT' должно быть в то же время, что и' foo.counter.T'. В крайнем случае я мог запечатать черту «Бар». – paradigmatic
К сожалению, это не сработает. Например, 'bar (Foo (IntCounter)) (0)' создает ошибку компиляции. – paradigmatic
@paradigmatic это проблема с оболочкой классов case: 'val c = Foo (IntCounter) .counter; val num: c.T = 5; error: type mismatch' Вероятно, вы даже не можете называть свою функцию 'дважды' – dk14