trait Vertex extends Entity {def ->[E <: Edge[_, _]](f: ((E) => Unit)*) = List()}trait Edge[A <: Vertex, B <: Vertex] extends Entity {val from: Aval to: B}
class Person(var name: String)extends Vertexclass Knows(val from: Person,val to: Person,var since: Int)extends Edge[Person, Person]
In the example, the from vertex instance that is the base of the query is a Person. The Knows edge type has as its "from" generic a Person, so it can be used only with "->" query based on a Person. The Knows "to" type is Person, so the result should be a List of Person:
In my graph API, I used:
subject <-< object >-> predicate
If you prefer,
nodeA <-< vertex1 >-> nodeB
In my domain, I end up dealing a lot with graphs vs bags of triples vs bags of bifurcating paths.
I also generalised this syntax to allow Iterable[node] and Iterable[edge] to be used in place of node and edge as a short-hand for generating lots of triples, and to allow chaining to build paths.
It sounds like you're saying that Vertex does not have type information about possible edges. That makes sense, since you can have multiple edges between different types. If so, if -> is defined on Vertex, it can get its type information only from its actual invocation. To my knowledge that means there must be type arguments for all relevant types. (I just had a very similar requirement.)However you can do your best to make all those types inferred. The most straightforward is to type the function:flavio -> ((_: Knows).since :>= 2011)In order to get the right type for A, provide -> with an implicit (all the more reason to pick a name that doesn't conflict.)In 2.10:implicit class VertexToEdgeQuery[A <: Vertex](vertex: A) {def >->[B, E <: Edge[A, B]](fs: (E => Unit)*): List[B] = ???}(I think you can figure out the boilerplate needed pre-2.10.)