The following is a list of items that we should probably get feedback on regarding the API: * Main thing we need to determine and then specify at the documentation level: expected semantics. Ideally, if a user wants to switch to a different graph representation, then for the most part they should just have to change their import and a few type signatures to specify which type they're using. The actual way each method operates should be independent from the actual instance. For example, multiple edges: I only just recently found out from someone else that PatriciaTree doesn't support multiple edges, and I had written my code assuming that it did. * Should we really bother having default definitions for empty and insert? * Should we keep the Eq constraint on Node values? Currently, it's only needed to allow for some default instances; if instead we require some eqNode method to be instantiated, then people can use Hash-able values or something for the Node type. * Should gmap perform the mappings in a decomposing fashion (i.e. for each node, decompose the graph to get its context, perform the map, put it back in), or match the current semantics (fromContexts . map f . toContexts)? Same goes with gfilter (though the folds need to be as they are currently probably). * We currently don't have newNodes defined; what semantics should it have? i.e. should it try to offer every currently unused node value in the graph, or just go "enumFrom (maxNode + 1)" ? Note that either way, having a default definition will require extra restrictions on the Node type and should probably be avoided (provide a function that can serve as a definition, but don't make it the default). * In general, how should we define functions (since we're currently using both): 1) a -> Graph -> b 2) Graph -> a -> b The second makes it easier to map over a list of values (e.g. getting the successor nodes for each specified node in a graph); however the former produces a nice morphism when partially applied and `b' is a Graph. * If we state that when creating a Context any loops must be in the successors field, should there be a variant of predecessors that includes any possible loops? * Should we bring the & operator back? (And fix the fixity of it so that we can do "c1 & c2 & c3 & empty" whilst we're at it?) * Should we really have Maybe and non-Maybe variants of lookupNode and lookupEdge? Should we just stick with the Maybe versions? Should we also change these to nodeLabel and nodeEdge? * Is `...' suitable for `(.).(.)' ? To me, `f ... g' looks like a case of 1) g, 2) ???, 3) f. * What should be the semantics of a function that returns new possible node IDs? i.e. if I delete a node, should it's ID then be available?