<br><div class="gmail_quote">On Tue, Aug 2, 2011 at 5:57 AM, Patrick Browne <span dir="ltr"><<a href="mailto:patrick.browne@dit.ie">patrick.browne@dit.ie</a>></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 => 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>> :t NilSet1<br>
NilSet1 :: Eq a => Set1 a<br>> :t NilSet2<br>NilSet2 :: Set2 a<br><br>But it doesn't give you that restriction back when you use it:<br><br>> let f (ConsSet1 v _) = v == v<br>> :t f<br>f :: Eq a => Set1 a -> Bool<br>
<br>You'd think that since you had to provide the evidence (Eq a) when you constructed ConsSet1, that it'd be available, but it'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) => Set2 t<br>
:t ConsSet1 1 NilSet1<br>
ConsSet1 1 NilSet1 :: forall t. (Num t) => Set1 t<br></blockquote><div><br>Remember that Eq is a superclass of Num.<br><br>> let f1 x = ConsSet1 x NilSet1<br>> let f2 x = ConsSet2 x NilSet2<br>> :t f1<br>f1 :: Eq a => a -> Set1 a<br>
f2 :: a -> Set2 a<br><br>'deriving Eq' on the definition of Set2 makes the instance 'instance Eq a => Eq (Set2 a)'. So you can construct Set2 at any type, and when the underlying type 'a' has equality, then 'Set2 a' does as well.<br>
<br></div></div> -- ryan<br>