Reputation: 19468
I am making a basic graph representation in Scala.
abstract class Vertex
class Edge (
val source: Vertex
val dest: Vertex
)
class Graph[V <: Vertex] {
...
}
At some point, I need to be able to sort a list of vertices in Graph[Vertex]
. I would like to do so by calling vertices.sorted
. If I make Vertex extend Ordered[Vertex]
then I don't actually have the right compareTo
since the ordering information is going to be data in the implemented subclass of Vertex
and compareTo
takes any Vertex
. But if I make my Vertex
implementation MyVertex
extend Ordered[MyVertex]
, then that information is not available in Graph[MyVertex]
.
What is the best solution to this problem? Should I be using an implicit Ordering? Is there a way to enforce that subclasses of Vertex
have an implicit Ordering on themselves?
I would rather not do the following:
class MyClass extends Vertex {
override def compare(that: Vertex) = that match {
case that: MyClass => // do the comparison
case _ => false
}
}
Update: maybe Graph
's constructor needs to take an Ordering[V]
?
Update: I could always restrict V <: Ordered[V]
but this does not scale. Is it possible to have multiple type restrictions?
Upvotes: 0
Views: 212
Reputation: 297205
Why not just this?
class Graph[V <: Vertex with Ordered[V]]
Or you could go the way of Ordering
too:
class Graph[V <: Vertex : Ordering]
Upvotes: 1
Reputation: 413
Why not design your Graph
class to contain a List
of Vertex
objects? Then you can use List's handy built-in sortWith
method.
For example:
class Graph(val Vertices:List[Vertex]) {
def sorted():Graph = {
new Graph(Vertices.sortWith((v1, v2) => { /* your comparison logic here */ }))
}
}
Hope that points you in the right direction.
Upvotes: 0
Reputation: 170745
Update: maybe
Graph
's constructor needs to take anOrdering[V]
?
That would be my preferred approach, because this way you may pass a different Ordering
if needed.
Update: I could always restrict
V <: Ordered[V]
but this does not scale. Is it possible to have multiple type restrictions?
Yes, since Scala has intersection types: V <: Ordered[V] with Something[V] with SomethingElse[V]
.
Upvotes: 1