Scala: параметр типа коллекции выдерживает "сбор", когда параметр типа является типом элемента
Обычно при сборе всех элементов последовательности, которые соответствуют определенному типу, результирующая коллекция имеет как тип исходной коллекции, так и тип, выбранный для:
trait Foo
trait Bar
trait Baz {
// Works
def def1(foo: Seq[Foo]): Seq[Foo with Bar] =
foo collect {case foobar: Bar => foobar}
}
Это даже работает, когда входной тип параметризован ограниченным типом члена, и все, что я хочу вернуть, - это последовательность, параметризованная связанным типом (не типом члена):
trait Baz {
type memberType <: Foo
// Works
def2(foo: Seq[memberType]): Seq[Foo with Bar] =
foo collect {case foobar: Bar => foobar}
}
Однако, это терпит неудачу, когда я действительно хочу вернуть последовательность, параметризованную типом члена:
trait Baz {
type memberType <: Foo
// Fails
def def3(foo: Seq[memberType]): Seq[memberType with Bar] =
foo collect {case foobar: Bar => foobar}
}
Сообщение об ошибке:
error: type mismatch;
found : Seq[this.Foo with this.Bar]
required: Seq[Baz.this.memberType with this.Bar]
foo collect {case foobar: Bar => foobar}
Чтобы восстановить функциональность, я могу включить тип члена в collect
вызов, но это кажется избыточным, учитывая, что каждый элемент должен соответствовать этому типу из-за подписи:
trait Baz {
type memberType <: Foo
// Works
def def4(foo: Seq[memberType]): Seq[memberType with Bar] =
foo collect {case foobar: memberType with Bar => foobar}
}
Есть ли способ определить последовательность типов элементов, чтобы они помнили свои типы элементов, когда collect
ред?
1 ответ
Это не ответ, а просто наблюдение. Это работает:
trait Baz[A <: Foo] {
def def3(foo: Seq[A]): Seq[A] =
foo collect {case foobar => foobar}
}
но это не
trait Baz[A <: Foo] {
def def3(foo: Seq[A]): Seq[A] =
foo collect {case foobar: Bar => foobar}
}
также это не:
trait Baz[A] {
def def3(foo: Seq[A]): Seq[A] =
foo collect {case foobar: Bar => foobar}
}
так что это похоже на эффект сопоставления с образцом; Я не думаю, что это имеет какое-либо отношение к collect
особенно. Каким-то образом он теряет информацию, как только вы добавляете тип в регистр соответствия:-/
Но, как и Кайто, я тоже был удивлен, что ваши первые два дела сработали. Должно быть (и это кажется разумным), чтобы алгоритм вывода типа отличал известный стабильный тип (Foo
) и параметр типа или член типа. Возможно, вам придется спросить в списке рассылки scala language, чтобы некоторые гуру компиляторов ответили на вопрос...