dimanche 16 décembre 2018

How to create a generic builder using TypeTag?

Given the following type hierarchy:

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]

I want to create a builder method that dynamically determines which concrete builder instance to return.

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

The above doesn't compile.

Error:(119, 29) No TypeTag available for DirectedEdge[V] case x if x <:< typeOf[DirectedEdge[V]] => new DirectedGraphBuilder[V, E]()

Error:(119, 29) not enough arguments for method typeOf: (implicit ttag: reflect.runtime.universe.TypeTag[DirectedEdge[V]])reflect.runtime.universe.Type. Unspecified value parameter ttag. case x if x <:< typeOf[DirectedEdge[V]] => new DirectedGraphBuilder[V, E]()





Aucun commentaire:

Enregistrer un commentaire