Как создать универсальный конструктор, используя TypeTag? - PullRequest
0 голосов
/ 17 декабря 2018

Учитывая следующую иерархию типов:

sealed trait Edge[T]
sealed trait WeightedEdge[T] extends Edge[T]
sealed abstract class AbstractUndirectedEdge[T] extends Edge[T]
case class UndirectedEdge[T](...) extends AbstractUndirectedEdge[T]
case class UndirectedWeightedEdge[T](...) extends AbstractUndirectedEdge[T] with WeightedEdge[T]
case class DirectedEdge[T](...) extends Edge[T]
case class DirectedWeightedEdge[T](...) extends WeightedEdge[T]

sealed abstract class GraphBuilder[V, E <: Edge[V]]
sealed class UndirectedGraphBuilder[V, E <: AbstractUndirectedEdge[V]] extends GraphBuilder[V, E]
sealed class DirectedGraphBuilder[V, E <: DirectedEdge[V]] extends GraphBuilder[V, E]

Я хочу создать метод компоновщика, который динамически определяет, какой конкретный экземпляр компоновщика будет возвращен..

Ошибка: (119, 29) TypeTag недоступен для DirectedEdge [V], случай x, если x <: <typeOf [DirectedEdge [V]] => new DirectedGraphBuilder [V, E] ()

Ошибка: (119, 29) недостаточно аргументов для метода typeOf: (неявный тег ttag: refle.runtime.universe.TypeTag [DirectedEdge [V]]) refle.runtime.universe.Type.Не указано значение параметра ttag.case x if x <: <typeOf [DirectedEdge [V]] => new DirectedGraphBuilder [V, E] ()

1 Ответ

0 голосов
/ 17 декабря 2018

Во-первых, вам необходимо указать TypeTag для V также:

def newBuilder[V, E <: Edge[V]](implicit tag: TypeTag[E], tag1: TypeTag[V]) = {
  tag.tpe match {
    case x if x <:< typeOf[DirectedEdge[V]] => new DirectedGraphBuilder[V, DirectedEdge[V]]()
    case _ => new UndirectedGraphBuilder[V, UndirectedEdge[V]]()
  }
}

Затем исправьте также тип создаваемого Edge.В какой-то момент типы должны быть исправлены тем или иным способом при создании.

Тогда это работает, хотя сценарий использования неясен.

...