Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>A very good example of an extensible graph structure is at <a href="http://www.scala-lang.org/node/124" rel="noreferrer">http://www.scala-lang.org/node/124</a></p> <p>I have thee ways to write yours. Note that in all cases there were some type changes required - i.e. GNode's type parameter needs to be covariant, and ConcreteGraph needs to be written with both a distinct node class and a type bound for Node. </p> <p>Once done, the first way to write dfs is to make it a method (it can be final if you want to avoid virtual dispatch overhead).</p> <pre><code>trait GNode[+Graph] { //... functions to get edges from this vertex, etc. ... } trait Graph { type Node &lt;: GNode[Graph] def dfs(nodeAction : Node =&gt; Unit) = print("dfsing!") } class ConcreteGraph extends Graph { class CGNode extends GNode[ConcreteGraph] type Node &lt;: CGNode } new ConcreteGraph dfs {node =&gt; println("foo")} </code></pre> <p>The second, with dfs not a method, seems to require just a bit of extra type hinting to use it.</p> <pre><code>def dfs[G &lt;: Graph](graph : G, nodeAction : G#Node =&gt; Unit) = print("dfsing!") dfs[ConcreteGraph](new ConcreteGraph, {node =&gt; println("foo")}) </code></pre> <p>The third way is with a curried dfs. Because of the way Scala's type inference works, that actually results in a cleaner interface</p> <pre><code>def dfs[G &lt;: Graph](graph : G)(nodeAction : G#Node =&gt; Unit) = print("dfsing!") dfs(new ConcreteGraph){node =&gt; println("foo")} </code></pre>
 

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