Thanks Roman.<br>I think I&#39;ll try out Data.Graph in that case.<br><br><div class="gmail_quote">On Mon, Jun 14, 2010 at 8:53 AM, Ivan Lazar Miljenovic <span dir="ltr">&lt;<a href="mailto:ivan.miljenovic@gmail.com">ivan.miljenovic@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">C K Kashyap &lt;<a href="mailto:ckkashyap@gmail.com">ckkashyap@gmail.com</a>&gt; writes:<br>

<br>
&gt; I love this list ... thanks Roman.<br>
&gt;<br>
&gt; I take it that there is nothing obviously inefficient about this approach to<br>
&gt; graph - as in the graph type.<br>
<br>
</div>Sure there is (using p = |V|, q = |E|):<br>
<br>
* Finding a particular node is O(p).<br>
<br>
* Adding an edge to an already existing node is also O(p).<br>
<br>
* Finding reverse edges is O(q) (probably more actually since you&#39;d be<br>
  checking every node that you have and then checking if the other end<br>
  is in the list of relationships).<br>
<br>
etc.<br>
<br>
The main advantage of your type is that it&#39;s O(1) to add a new node +<br>
successor edges.<br>
<br>
Now, depending upon what you&#39;re wanting to do, this may suffice.<br>
However, there are a couple of alternatives:<br>
<br>
* Use Data.Graph from containers<br>
<br>
* Use either Data.Graph.Inductive.Tree or<br>
  Data.Graph.Inductive.PatriciaTree (which has better performance but<br>
  doesn&#39;t allow multiple edges) from fgl.<br>
<br>
* If you still want a custom type, then something like &quot;Map v (Set v)&quot;<br>
  would be much more efficient than using [(v, [v])] (this could be<br>
  improved at the expense of disk space and more bookkeeping by using<br>
  &quot;Map v (Set v, Set v)&quot; to store both successor and predecessor edges).<br>
<div><div></div><div class="h5"><br>
&gt;<br>
&gt;<br>
&gt; On Mon, Jun 14, 2010 at 12:02 AM, Roman Cheplyaka &lt;<a href="mailto:roma@ro-che.info">roma@ro-che.info</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt; * C K Kashyap &lt;<a href="mailto:ckkashyap@gmail.com">ckkashyap@gmail.com</a>&gt; [2010-06-13 22:45:44+0530]<br>
&gt;&gt; &gt; Hi,<br>
&gt;&gt; &gt; I am trying to write a routine that would generate a graph - where each<br>
&gt;&gt; &gt; vertex would be a string.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; type Graph v = [(v,[v])]  -- list of tuples of vertices and adjacent<br>
&gt;&gt; &gt; vertices list<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; addEdgeToGraph :: Graph -&gt; String -&gt; String -&gt; Graph<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; I am having trouble coming up with the body of this function - that takes<br>
&gt;&gt; &gt; the original graph, and an edge (string -&gt; string) and the produces the<br>
&gt;&gt; new<br>
&gt;&gt; &gt; graph.<br>
&gt;&gt;<br>
&gt;&gt; If you know that the vertices already exist and you need only to add an<br>
&gt;&gt; edge, then you just go through all the vertices, compare current vertex<br>
&gt;&gt; to given ones and if they match add a vertex.<br>
&gt;&gt;<br>
&gt;&gt; \begin{code}<br>
&gt;&gt; addEdgeToGraph :: Graph String -&gt; String -&gt; String -&gt; Graph String<br>
&gt;&gt; addEdgeToGraph gr v1 v2 = map modify gr<br>
&gt;&gt;    where<br>
&gt;&gt;    modify (v,vs) | v == v1 = (v,v2:vs)<br>
&gt;&gt;    modify (v,vs) | v == v2 = (v,v1:vs)<br>
&gt;&gt;    modify x = x<br>
&gt;&gt; \end{code}<br>
&gt;&gt;<br>
&gt;&gt; Otherwise it is possible that one (or both) vertex doesn&#39;t exist yet, so<br>
&gt;&gt; you first need to &quot;try&quot; the first version, and if at least one of the<br>
&gt;&gt; vertex is not found, add it to the list. You can use fold for this.<br>
&gt;&gt;<br>
&gt;&gt; \begin{code}<br>
&gt;&gt; addEdgeToGraph&#39; :: Graph String -&gt; String -&gt; String -&gt; Graph String<br>
&gt;&gt; addEdgeToGraph&#39; gr v1 v2 =<br>
&gt;&gt;    let (newgr, (foundV1, foundV2)) = foldr modify ([],(False,False)) gr<br>
&gt;&gt;    in<br>
&gt;&gt;        (if foundV1 then [] else [(v1,[v2])]) ++<br>
&gt;&gt;        (if foundV2 then [] else [(v2,[v1])]) ++<br>
&gt;&gt;        newgr<br>
&gt;&gt;    where<br>
&gt;&gt;    modify (v,vs) (lst,(_,foundV2)) | v == v1 = ((v,v2:vs):lst,<br>
&gt;&gt; (True,foundV2))<br>
&gt;&gt;    modify (v,vs) (lst,(foundV1,_)) | v == v2 = ((v,v1:vs):lst,<br>
&gt;&gt; (foundV1,True))<br>
&gt;&gt;    modify v (lst,f) = (v:lst,f)<br>
&gt;&gt; \end{code}<br>
&gt;&gt;<br>
&gt;&gt; --<br>
&gt;&gt; Roman I. Cheplyaka :: <a href="http://ro-che.info/" target="_blank">http://ro-che.info/</a><br>
&gt;&gt; &quot;Don&#39;t let school get in the way of your education.&quot; - Mark Twain<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; Haskell-Cafe mailing list<br>
&gt;&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt;&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;&gt;<br>
<br>
--<br>
</div></div><font color="#888888">Ivan Lazar Miljenovic<br>
<a href="mailto:Ivan.Miljenovic@gmail.com">Ivan.Miljenovic@gmail.com</a><br>
<a href="http://IvanMiljenovic.wordpress.com" target="_blank">IvanMiljenovic.wordpress.com</a><br>
</font></blockquote></div><br><br clear="all"><br>-- <br>Regards,<br>Kashyap<br>