Here's a (somewhat contrived) example to illustrate what I would like to do
pub trait Node: Eq + Hash {
type Edge: Edge;
fn get_in_edges(&self) -> Vec<&Self::Edge>;
fn get_out_edges(&self) -> Vec<&Self::Edge>;
}
pub trait Edge {
type Node: Node;
fn get_src(&self) -> &Self::Node;
fn get_dst(&self) -> &Self::Node;
}
pub trait Graph {
type Node: Node;
type Edge: Edge;
fn get_nodes(&self) -> Vec<Self::Node>;
}
pub fn dfs<G: Graph>(root: &G::Node) {
let mut stack = VecDeque::new();
let mut visited = HashSet::new();
stack.push_front(root);
while let Some(n) = stack.pop_front() {
if visited.contains(n) {
continue
}
visited.insert(n);
for e in n.get_out_edges() {
stack.push_front(e.get_dst());
}
}
}
Is there a way to express in the Graph
trait that Graph::Node
must be the same type as Graph::Edge::Node
and that Graph::Edge
must be the same type as Graph::Node::Edge
?
I remember reading something about a feature (not implemented at the time) that would allow richer constraints for this sort of thing, but I don't remember its name and cannot find it.
In
Graph
's definition, you can constrain each associated type's associated type (!) to be equal to the corresponding associated type inGraph
.