I tried to do collection matching in Scala without using scala.reflect.ClassTag
case class Foo(name: String)
case class Bar(id: Int)
case class Items(items: Vector[AnyRef])
val foo = Vector(Foo("a"), Foo("b"), Foo("c"))
val bar = Vector(Bar(1), Bar(2), Bar(3))
val fc = Items(foo)
val bc = Items(bar)
we can not do this:
fc match {
case Items(x) if x.isInstanceOf[Vector[Foo]]
}
because:
Warning: non-variable type argument Foo in type scala.collection.immutable.Vector[Foo] (the underlying of Vector[Foo]) is unchecked since it is eliminated by erasure
and this:
fc match {
case Items(x: Vector[Foo]) =>
}
but we can do this:
fc match {
case Items(x@(_: Foo) +: _) => ...
case Items(x@(_: Bar) +: _) => ...
}
bc match {
case Items(x@(_: Foo) +: _) => ...
case Items(x@(_: Bar) +: _) => ...
}
As you can see, we are check - is collection Foo + vector or Bar + vector.
And here we are have some problems:
- We can do Vector(Foo("1"), Bar(2)), and this is will be match with Foo.
- We are still need "val result = x.asInstanceOf[Vector[Bar]]" class casting for result extraction
Is there are some more beautiful way? Like this:
fc match {
case Items(x: Vector[Foo]) => // result is type of Vector[Foo] already
}
ClassTag
... The "Off topic" section should really have an "XY-problem" subsection. – Dima