После моего предыдущего вопроса пришел быстрый и отличный ответ, однако оказалось, что мой пример недостаточно хорошо соответствовал моему фактическому производственному коду. Итак, мне нужна новая реализация метода collect.
Второй фруктовый мир (с довольно забавными фруктовыми деревьями):
class Fruit {
var seeds:Array[Fruit] = Array()
def naiveCollect[F <: Fruit]:Array[Fruit] = this match {
case f:F => Array(this)
case _ => seeds.map(_.select[F]).flatten.toArray
}
}
class Apple extends Fruit
class Pear extends Fruit
class GrannySmith extends Apple
Не работает из-за стирания типа:
var tree = new Fruit { seeds = Array(
new Apple,
new Pear,
new GrannySmith,
new Pear { seeds = Array(
new Apple,
new Pear)},
new Apple)}
scala> tree.naiveCollect[Apple]
res1: Array[Fruit] = Array($anon$2@5a4b99fa)
// wanted output: Apple, GrannySmith, Apple, Apple
РЕДАКТИРОВАТЬ, РЕШЕНИЕ1:
Оказывается, мне удалось создать что-то, что работает с использованием PartialFunction, как в стандартной библиотеке.
class Fruit {
...
def clumsyCollect[F](pf:PartialFunction[Fruit, F]):Seq[F] =
if (pf.isDefinedAt(this))
List(pf(this))
else
seeds.flatMap(_.selectPartial[F](pf))
}
Вариант использования:
tree.clumsyCollect { case a:Apple => a }
Любые альтернативы или советы по очистке этой системы все равно будут хороши!