<br><div class="gmail_quote">On Tue, Aug 2, 2011 at 5:57 AM, Patrick Browne <span dir="ltr">&lt;<a href="mailto:patrick.browne@dit.ie">patrick.browne@dit.ie</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
data Eq a =&gt; Set1 a = NilSet1 | ConsSet1 a (Set1 a)<br>
data         Set2 a = NilSet2 | ConsSet2 a (Set2 a) deriving Eq<br></blockquote><div><br>The former declaration is a language wart, IMO.  All it does is attach a restriction to the constructors of Set1; try<br><br>&gt; :t NilSet1<br>
NilSet1 :: Eq a =&gt; Set1 a<br>&gt; :t NilSet2<br>NilSet2 :: Set2 a<br><br>But it doesn&#39;t give you that restriction back when you use it:<br><br>&gt; let f (ConsSet1 v _) = v == v<br>&gt; :t f<br>f :: Eq a =&gt; Set1 a -&gt; Bool<br>
<br>You&#39;d think that since you had to provide the evidence (Eq a) when you constructed ConsSet1, that it&#39;d be available, but it&#39;s not.<br><br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

-- Seems to have same type<br>
:t ConsSet2 1 NilSet2<br>
ConsSet2 1 NilSet2 :: forall t. (Num t) =&gt; Set2 t<br>
:t ConsSet1 1 NilSet1<br>
ConsSet1 1 NilSet1 :: forall t. (Num t) =&gt; Set1 t<br></blockquote><div><br>Remember that Eq is a superclass of Num.<br><br>&gt; let f1 x = ConsSet1 x NilSet1<br>&gt; let f2 x = ConsSet2 x NilSet2<br>&gt; :t f1<br>f1 :: Eq a =&gt; a -&gt; Set1 a<br>
f2 :: a -&gt; Set2 a<br><br>&#39;deriving Eq&#39; on the definition of Set2 makes the instance  &#39;instance Eq a =&gt; Eq (Set2 a)&#39;.  So you can construct Set2 at any type, and when the underlying type &#39;a&#39; has equality, then &#39;Set2 a&#39; does as well.<br>
<br></div></div>  -- ryan<br>