これは、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
}
私もそのコンストラクタのパラメータの1つとしてFoo
のサブタイプを取る別のクラスを持っている、そしてそれはBar
かBaz
のかどうかに基づいて特定の事柄を行います。
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
}
これがうまく働いたが、入力に起因する未チェックの種類についての警告につながった:そうは次のようにリンクされ、質問への受け入れ答えて
は、それがこのアイデアを実装するために、ユーザー@mariosによって私に示唆されました消去(Baz
の場合はMap
に一致しているので)。私の特別なケースでは、しかし、これらは安全に無視することができました。しかし、この場合には、私は私の質問は、なぜ、ある
[error] Qux.scala:4: type mismatch;
[error] found : X#A
[error] required: Array[String]
[error] case Bar(_, _) => BarProcessor(m).doStuff(rows)
[error] ^
のようなエラーが出
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]]
}
}
}
:?しかし、私はこれを避けることができればと思った、とこのような何かを書き込もうとしましたかこれらの2つのコードスニペットは実際にはまったく異なるようには見えません。なぜ、型メンバーにアクセスするのが最初のケースでは動作しますが、2番目では動作しませんか?