I have a record describing a graph as sets of nodes and edges:
data MyGraph a = MyGraph {
nodes :: Set a,
edges :: Set (a,a),
components :: UnionFindM a -- ?
}
emptyGraph = MyGraph{
nodes = empty, edges = empty,
components = emptyUnionFind singleton union --?
}
addEdge g (a,b) = g{
edges = (a,b) `insert` (edges g),
components = (components g) >>= (equate a b) -- ?
}
Since I won't ever remove edges, I want to track the connected components using a union-find structure (which I could easily update when adding an edge), because I want to map over the connected components, so it would be useful to keep them as a set of sets, too. And of course I want to get the component for a node.
I found the equivalence library, which I chose because I can't see how I would create sets with union-find and persistent-equivalence needs to know the value range.
Now I can create relations, and return the set of sets using:
import Control.Monad(liftM)
import Data.Equivalence.Monad
import Data.Set(singleton, union, fromList)
f = runEquivM singleton union $ do
equate "foo" "bar"
equate "bar" "baz"
(liftM fromList) $ mapM classDesc ["foo","bar","baz","one","two"]
>>> f
fromList [fromList ["bar","baz","foo"],fromList ["one"],fromList ["two"]]
But: using fromList
is very naive, it should be possible to get all equivalence classes from the internal data structure directly.
And, more importantly: how can I store the equivalence relation in my data structure?