scala custom traversable of Seq[A]

Viewed 76

I am trying to make my Graph to implement Traversable for it's edges. I have a type of edge called Edge[Node, EdgeType]. My edge is a final case class. The code looks like this:

class Graph[Node, Type] extends Traverasble[Edge[Node, Type]]

I saw this post about creating a custom Traversable, but I can't make it work. My Graph knows it's element, Edge, but not its parameter type, Node and EdgeType. I couldn't make the Factory to understand those generics.

object Graph extends TraversableFactory[Graph] {
    implicit def canBuildFrom[A<:Edge[_,_]]: CanBuildFrom[Coll, A, Graph[_]] = new GenericCanBuildFrom[A]
    def newBuilder[A<:Edge[_,_]] = new ListBuffer[A] mapResult (x => new Graph(x:_*))
}

I tried to use higherKinds, but I don't see how solve it with same either.

Do you know how I can solve this? This problem returns everytime a class with some generics extends Traversable that it's Elem is a composition of the class generics.

1 Answers

It is not clear what you are trying to achieve by implementing custom TraversableFactory. Those machinery is there to support generic collections i.e. collections that can store elements of arbitrary type. This is important because the supported methods include methods that can change type of the element such as .map. What it the expected type of the intCol and mapped in the following code:

val graph: Graph[SomeNode, SomeType] = ???
val intCol = graph.companion.empty[Int]
val mapped = graph.map(edge => 42) // yes fixed value just for an example

intCol and mapped should definitely be some subtype of Traversable[Int]. Can you Graph represent such an object? If no, then your Graph is not a generic collection and should not have a custom companion TraversableFactory object.

P.S. Since you didn't provide any description of what you are really trying to achieve, it is hard to guess, but it might be that what you really want is inheriting from TraversableLike (or IterableLike) rather than Traversable. The main difference is that TraversableLike do not define companion so can represent a collection specific for just one type.

Related