Если я правильно понял ваш вопрос, ответ таков: вы можете сделать это, если Typed
является ковариантным в T
, т.е. trait Typed[+T]
.
Пример
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Typed[+T: Manifest] {
override def toString = "Typed[" + implicitly[Manifest[T]].toString + "]"
}
trait Test {
def testMap: Map[Typed[_], Int]
def foo = testMap flatMap { case (t, s) => Seq.fill(s)(t) }
}
val bar = new Test {
def testMap = Map(new Typed[Double]() -> 3, new Typed[Int]() -> 5)
}
// Hit Ctrl-D
scala> bar.foo
res0: scala.collection.immutable.Iterable[Seq[Typed[Any]]] = List(Typed[Double], Typed[Double], Typed[Double], Typed[Int], Typed[Int], Typed[Int], Typed[Int], Typed[Int])
Обратите внимание, что я сделал Typed
класс в этом примере, чтобы получить лучший вывод. Вы можете, конечно, придерживаться trait
.
Теперь, зачем здесь нужна ковариация?
Ковариация в основном означает, что если A <: B
, то X[A] <: X[B]
. Таким образом, если вы объявили testMap
как Map[Typed[Any], Int]
, в то время как Typed
были инвариант , вам не разрешили перейти, например, Typed[Double]
для Typed[Any]
, хотя Double <: Any
. Здесь компилятор scala, по-видимому, заменяет _
на Any
в ковариантном случае (подробности см. В комментарии к расширению).
Для объяснения проблемы, связанной с подчеркиванием, я бы обратился к ответу Луиджи.