<br><br><div class="gmail_quote">On Fri, Apr 30, 2010 at 11:53 PM, 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="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">Jason Dagit &lt;<a href="mailto:dagit@codersbase.com">dagit@codersbase.com</a>&gt; writes:<br>
<br>
&gt; On Fri, Apr 30, 2010 at 11:08 PM, Ivan Lazar Miljenovic &lt;<br>
&gt; <a href="mailto:ivan.miljenovic@gmail.com">ivan.miljenovic@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; You&#39;re putting the constraint in the wrong places: put the &quot;(Cls a) =&gt; &quot;<br>
&gt;&gt; in the actual functions where you need it.<br>
&gt;&gt;<br>
&gt;<br>
&gt; That&#39;s solid advice in general, but it&#39;s still not going to work here if any<br>
&gt; of the functions needed for the instance of Graph require the type class<br>
&gt; constraint.<br>
<br>
</div>The Graph class doesn&#39;t care what the labels are, so it should matter<br>
about the constraint.<br></blockquote><div><br></div><div>Perhaps this &quot;working&quot; example illustrates the change I want to make.  Working in the sense that it type checks but it&#39;s a silly example just to illustrate the point:</div>
<div><br></div><div>\begin{code}</div><div><div>{-# LANGUAGE MultiParamTypeClasses #-}</div><div>{-# LANGUAGE FlexibleInstances #-}</div><div>module Graph where</div><div><br></div><div>import Data.Graph.Inductive.Graph hiding (Graph)</div>
<div><br></div><div>-- Defive some arbitrary class, and give it a &#39;boring&#39;</div><div>-- reason to use it.</div><div>class Cls a where</div><div>  boring :: a</div><div><br></div><div>data Blah = Blah</div><div><br>
</div><div>-- Make sure we have at least one instance, but not really needed for this example</div><div>instance Cls Blah where</div><div>  boring = Blah</div><div><br></div><div>data B a = B [a]</div><div><br></div><div>
data GrB a b = GrB (B a)</div><div><br></div><div>-- Just copy the bits from FGL that are interesting here</div><div>class Graph gr a b where</div><div>  empty     :: gr a b</div><div>  -- | True if the given &#39;Graph&#39; is empty.</div>
<div>  isEmpty   :: gr a b -&gt; Bool</div><div>  -- | Create a &#39;Graph&#39; from the list of &#39;LNode&#39;s and &#39;LEdge&#39;s.</div><div>  mkGraph   :: [LNode a] -&gt; [LEdge b] -&gt; gr a b</div><div>  -- | A list of all &#39;LNode&#39;s in the &#39;Graph&#39;.</div>
<div>  labNodes  :: gr a b -&gt; [LNode a]</div><div><br></div><div>instance Cls a =&gt; Graph GrB a b where</div><div>  empty = GrB (B [boring])</div><div>  isEmpty (GrB (B [])) = True</div><div>  isEmpty _            = False</div>
<div>  mkGraph _ _ = GrB (B [])</div><div>  labNodes _ = []</div></div><div>\end{code}</div><div><br></div><div>The Graph class is actually unchanged other than mentioning &#39;a&#39; and &#39;b&#39;.  This mention of &#39;a&#39; and &#39;b&#39; allows instance writers to add contexts other than () when defining instances.</div>
<div><br></div><div>Jason</div></div>