Note that there are some explanatory texts on larger screens.

plurals
  1. POMixing type parameters and abstract types in scala
    text
    copied!<p>I am trying to use the answer of <a href="https://stackoverflow.com/questions/2059601/circular-type-parameters-definition-in-scala">a preceding question</a> to implement a small graph library. The idea is to consider graphs as colections, where vertices wrap collection elements.</p> <p>I would like to use abstract types to represent Vertex and Edge types (because of type safety) and I want to use type parameters to represent the type of the collection elements (because I want to define them at instantiation easily).</p> <p>However, when trying the most basic example I can think about, I am stuck with compile errors. Here is the example:</p> <pre><code>package graph abstract class GraphKind[T] { type V &lt;: Vertex[T] type G &lt;: Graph[T] def newGraph(): G abstract class Graph[T] extends Collection[T]{ self: G =&gt; def vertices(): List[V] def add(t: T): Unit def size(): Int def elements(): Iterator[T] } trait Vertex[T] { self: V =&gt; def graph(): G def value(): T } } </code></pre> <p>And here is the basic implementations:</p> <pre><code>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 + ")" } } </code></pre> <p>When trying to compile, I get:</p> <pre><code>/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 </code></pre> <p>I have absolutely no idea of the meaning of these errors... However, if I specialize the type T in the implementation (<code>class SimpleGraphKind extends GraphKind[Int]</code> I get only the first error. </p> <p>Do you have some ideas ?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload