简体   繁体   中英

Dependent classes and types

Let's say that I want to create a simple graph representation where Vertex and Edge and their types depend on each other. A concrete implementation could look something like this:

case class Edge(id: Int, label: String, endpoints: (Vertex, Vertex))
case class Vertex(id: Int, data: Data, edges: Map[Int, Edge])

Edge depends on Vertex and vice versa. What I really want is for id , data etc to have generic types. And I wonder how to design this the best way?

trait Vertex[A, B] {
  def id: A
  def data: B
  // What about types for the edges etc?
}

trait Edge[A, ...] {
  def id: A
  def label: String
  def endpoints: (Vertex[...], Vertex[...])
}

A simple example of this would be much appreciated.

What is wrong with re-using the type parameters?

trait Vertex[A, B] {
  def id: A
  def data: B
  def edges: Map[A, Edge[A, B]]
}

And then in Edge :

trait Edge[A, B] {
  def id: A
  def label: String
  def endpoints: (Vertex[A, B], Vertex[A, B])
}

Since Vertex and Edge can have different ID types, you may want to have Vertex and Edge be inner traits of a Graph trait, which has all the type parameters. That way, Vertex can know about the Edge trait's ID type, and Edge can know about the Vertex trait's ID and Data types.

trait Graph[VertexID, EdgeID, Data] {

  trait Vertex {
    def id: VertexID
    def data: Data
    def edges: Map[EdgeID, Edge]
  }

  trait Edge {
    def id: EdgeID
    def label: String
    def endpoints: (Vertex, Vertex)
  }

}

Incidentally, due to path-dependent types, Edge would only be able to have endpoints which are in the same Graph, and Vertex would only be able to have edges which are in the same Graph.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM