Исправление предупреждения предложения соответствия путем избавления от параметра типа - PullRequest
1 голос
/ 07 июня 2011

Я хочу реализовать следующее исчерпывающее совпадение, но я не могу понять, чтобы удалить параметр типа и, следовательно, предупреждение о его удалении:

sealed trait Q[+V]
case object QEmpty extends Q[Nothing]
sealed trait QNonEmpty[V] extends Q[V] {
  def foo: V
}
final class QLeaf[V](val foo: V) extends QNonEmpty[V]
final class QNode[V](val foo: V, var children: Array[Q[V]]) extends QNonEmpty[V]

def test[V](n: Q[V]): String = n match {
  case QEmpty          => "empty"
  case n: QNonEmpty[V] => n.foo.toString  // warning: type parameter V is erased
}

в моем конкретном случае телоcase n совпадение очень большое, и я не хочу добавлять больше предложений совпадения, чтобы вместо него сравнивать QLeaf и QNode (поскольку в моем конкретном случае имеется более двух подклассов, они также являются изменяемыми и поэтомуне должно быть тематических занятий).разрешенный тип должен быть QNonEmpty[V], он не может быть QNonEmpty[_].

Можно ли создать экстрактор для QNonEmpty, который соответствует QLeaf и QNode?

1 Ответ

3 голосов
/ 07 июня 2011

Вы можете использовать экзистенциальные типы для сопоставления с типом со стертыми параметрами:

type AnyNonEmpty = QNonEmpty[X] forSome { type X }

in match {
  case x: AnyNonEmpty => //...
}

Экстрактор может выглядеть так:

object QNonEmpty {
  def unapply(in: QNonEmpty[_]): Option[Any] = Some(in.foo)
}

def test[ V ]( n: Q[ V ]) : String = n match {
   case QEmpty => "empty"
   case QNonEmpty(foo) => foo.toString
}

Я не думаю, что вы можетеНапишите безопасное извлечение типов, так как в вашем примере кода параметр типа для метода также удаляется.Может быть, вам стоит подумать о добавлении метода fold к вашей характеристике и переписать ваш пример так:

sealed trait Q[ +V ] {
  def fold[A](e: => A, f: V => A): A = e
}

case object QEmpty extends Q[ Nothing ]

sealed trait QNonEmpty[ V ] extends Q[ V ] {
  def foo: V
  override def fold[A](e: => A, f: V => A) = f(foo)
}

// ...

def test[V](n: Q[V]) = n.fold("empty", _.toString)
...