Estoy tratando de usar la respuesta de a preceding question para implementar una pequeña biblioteca de gráficos. La idea es considerar los gráficos como colecciones, donde los vértices envuelven los elementos de la colección.Mezclando parámetros de tipo y tipos abstractos en scala
Me gustaría utilizar tipos abstractos para representar los tipos Vertex y Edge (debido a la seguridad del tipo) y usar parámetros de tipo para representar el tipo de elementos de colección (porque quiero definirlos fácilmente en la creación de instancias).
Sin embargo, al intentar el ejemplo más básico en el que puedo pensar, estoy atascado con errores de compilación. Aquí está el ejemplo:
package graph
abstract class GraphKind[T] {
type V <: Vertex[T]
type G <: Graph[T]
def newGraph(): G
abstract class Graph[T] extends Collection[T]{
self: G =>
def vertices(): List[V]
def add(t: T): Unit
def size(): Int
def elements(): Iterator[T]
}
trait Vertex[T] {
self: V =>
def graph(): G
def value(): T
}
}
y aquí está el implementaciones básicas:
class SimpleGraphKind[T] extends GraphKind[T] {
type G = GraphImpl[T]
type V = VertexImpl[T]
def newGraph() = new GraphImpl[T]
class GraphImpl[T] extends Graph[T] {
private var vertices_ = List[V]()
def vertices = vertices_
def add(t: T) { vertices_ ::= new VertexImpl[T](t,this) }
def size() = vertices_.size
def elements() = vertices.map(_.value).elements
}
class VertexImpl[T](val value: T, val graph: GraphImpl[T]) extends Vertex[T] {
override lazy val toString = "Vertex(" + value.toString + ")"
}
}
Al intentar compilar, obtengo:
/prg/ScalaGraph/study/Graph.scala:10: error: illegal inheritance;
self-type GraphKind.this.G does not conform to Collection[T]'s selftype Collection[T]
abstract class Graph[T] extends Collection[T]{
^
/prg/ScalaGraph/study/Graph.scala:33: error: illegal inheritance;
self-type SimpleGraphKind.this.GraphImpl[T] does not conform to SimpleGraphKind.this.Graph[T]'s selftype SimpleGraphKind.this.G
class GraphImpl[T] extends Graph[T] {
^
/prg/ScalaGraph/study/Graph.scala:36: error: type mismatch;
found : SimpleGraphKind.this.VertexImpl[T]
required: SimpleGraphKind.this.V
def add(t: T) { vertices_ ::= new VertexImpl[T](t,this) }
^
/prg/ScalaGraph/study/Graph.scala:38: error: type mismatch;
found : Iterator[T(in class SimpleGraphKind)]
required: Iterator[T(in class GraphImpl)]
def elements() = vertices.map(_.value).elements
^
/prg/ScalaGraph/study/Graph.scala:41: error: illegal inheritance;
self-type SimpleGraphKind.this.VertexImpl[T] does not conform to SimpleGraphKind.this.Vertex[T]'s selftype SimpleGraphKind.this.V
class VertexImpl[T](val value: T, val graph: GraphImpl[T]) extends Vertex[T] {
^
5 errors found
no tengo absolutamente ninguna idea del significado de estos errores ... Sin embargo, si especializo el tipo T en la implementación (class SimpleGraphKind extends GraphKind[Int]
obtengo solo el primer error.
¿Tiene algunas ideas?
¿Podría aclarar por qué quiere que un gráfico sea una colección? –
Una aplicación de esta biblioteca sería implementar un tipo de autómata celular en un gráfico (el otro es la investigación de redes complejas). Entonces podría ser agradable acceder directamente a los objetos de celda encerrados en los vértices ... Pero si tiene una idea de solución sin el gráfico como función de recopilación, también estoy interesado. – paradigmatic
Todavía no estoy seguro de ver la conexión. ¿Cómo verías que tu biblioteca gráfica se distingue de, digamos, JGraphT? ¿Es un enfoque funcional para los gráficos? –