Это this question.Согласование образцов с ADT и элементами типа
У меня есть ADT моделируется следующим образом:
sealed trait Foo {
type A
def method: A
}
case class Bar(p: T, q: S) extends Foo {
type A = Array[String]
def method: A = // implementation
}
case class Baz(p: T, q: S) extends Foo {
type A = Map[Array[String], Array[String]]
def method: A = // implementation
}
У меня есть еще один класс, который принимает подтип Foo
в качестве одного из параметров конструктора, и делает конкретные вещи, основанные на будь то Bar
или Baz
.
В принятом ответе на вопрос связан, он предложил мне пользователем @marios, чтобы реализовать эту идею так:
class Qux[X <: Foo](foo: X) {
val m: X#A = foo.method
def process = m match {
case a: Bar#A => // do stuff with Bar
case b: Baz#A => // do other stuff with Baz
}
Это работало хорошо, но привело к предупреждениям о непроверенных типов в зависимости от типа стирание (поскольку я согласен на Map
, в случае Baz
). Однако в моем конкретном случае их можно было безоговорочно игнорировать. Но я подумал, если я мог бы избежать этого, и попытался написать что-то вроде этого:
class Qux[X <: Foo](foo: X) {
def process(param: U) = {
val m: X#A = foo.method
foo match {
case Bar(_, _) => BarProcessor(m).doStuff(param) // where BarProcessor expects m to be an Array[String]
case Baz(_, _) => BazProcessor(m.keys).doStuff(param, m.values) // do related stuff using m, but where m is instead now a Map[Array[String], Array[String]]
}
}
}
Однако, в этом случае я получаю ошибки как
[error] Qux.scala:4: type mismatch;
[error] found : X#A
[error] required: Array[String]
[error] case Bar(_, _) => BarProcessor(m).doStuff(rows)
[error] ^
Мой вопрос, почему? Кажется, что эти два фрагмента кода действительно не отличаются друг от друга, поэтому почему доступ к члену типа работает в первом случае, но не во втором?