You can roll out your extension methods on top level or on inner trait level.
To enrich your graph with your own methods on top level is straightforward:
implicit class ExtGraph[N, E <: Edge[N]](val g: Graph[N, E]) {
def foo: String = "bar"
}
Graph(1 ~ 2)foo // String: "bar"
One way to enrich inner types is to bank on type projection.
To add your extension methods to NodeT you can do:
implicit class ExtInnerNode[N, E <: Edge[N]](node: Graph[N, E]#NodeT) {
def outOverInDegree: Int = node.outDegree - node.inDegree
}
Graph(1 ~> 2).nodes foreach {
case n if n.outer == 1 => n.outOverInDegree // Int: 1
case n if n.outer == 2 => n.outOverInDegree // Int: -1
case _ => fail()
}