<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7654.12">
<TITLE>RE: [Haskell-cafe] Type class context propagation investigation[MESSAGE NOT SCANNED]</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=2>Thanks. GHC at one stage suggested I add (Num a) =&gt;<BR>
to my Num instance (after I'd added (Eq a) =&gt; to my Eq<BR>
instance) and I didn't make the connection.<BR>
<BR>
<BR>
-----Original Message-----<BR>
From: Ryan Ingram [<A HREF="mailto:ryani.spam@gmail.com">mailto:ryani.spam@gmail.com</A>]<BR>
Sent: Thu 28/05/2009 01:18<BR>
To: Paul Keir<BR>
Cc: haskell-cafe@haskell.org<BR>
Subject: Re: [Haskell-cafe] Type class context propagation investigation[MESSAGE NOT SCANNED]<BR>
<BR>
Think of classes like data declarations; an instance with no context<BR>
is a constant, and one with context is a function.&nbsp; Here's a simple<BR>
translation of your code into data; this is very similar to the<BR>
implementation used by GHC for typeclasses:<BR>
<BR>
&gt; data EqDict a = EqDict { eq :: a -&gt; a -&gt; Bool }<BR>
&gt; data ShowDict a = ShowDict { show :: a -&gt; String }<BR>
&gt; data NumDict a = NumDict { num_eq :: EqDict a, num_show :: ShowDict a, plus :: a -&gt; a -&gt; a }<BR>
<BR>
The goal of the compiler is to turn your instance declarations into<BR>
these structures automatically.&nbsp; Here's a translation of your original<BR>
instance:<BR>
<BR>
&gt; eq_foo :: EqDict (Foo a)<BR>
&gt; eq_foo = EqDict { eq = undefined }<BR>
<BR>
&gt; show_foo :: ShowDict (Foo a)<BR>
&gt; show_foo = ShowDict { show = undefined }<BR>
<BR>
&gt; num_foo :: NumDict (Foo a)<BR>
&gt; num_foo = NumDict { num_eq = eq_foo, num_show = show_foo, plus = undefined }<BR>
<BR>
Now if you add a constraint on the &quot;Eq&quot; instance, this means that eq<BR>
from eq_foo might refer to eq in the dictionary for &quot;a&quot;.&nbsp; How do we<BR>
get that dictionary?&nbsp; We just pass it as an argument!<BR>
<BR>
&gt; eq_foo :: EqDict a -&gt; EqDict (Foo a)<BR>
&gt; eq_foo eq_a = EqDict { eq = undefined }<BR>
<BR>
However, you don't have a similar constraint on the Num instance:<BR>
<BR>
&gt; num_foo :: NumDict (Foo a)<BR>
&gt; num_foo = NumDict { num_eq = eq_foo &lt;something&gt;, num_show = show_foo, plus = undefined }<BR>
<BR>
The compiler wants to fill in &lt;something&gt;, but it can't; it doesn't<BR>
have a dictionary of the type EqDict a.&nbsp; So it tells you so, saying<BR>
that Eq a is missing!<BR>
<BR>
Once you add the (Eq a) constraint to the Num instance, it works:<BR>
<BR>
&gt; num_foo :: EqDict a -&gt; NumDict (Foo a)<BR>
&gt; num_foo eq_a = NumDict { num_eq = eq_foo eq_a, num_show = show_foo, plus = undefined }<BR>
<BR>
You can also add a (Num a) constraint instead, and the compiler can<BR>
use it to get the Eq instance out:<BR>
<BR>
&gt; num_foo :: NumDict a -&gt; NumDict (Foo a)<BR>
&gt; num_foo num_a = NumDict { num_eq = eq_foo (num_eq num_a), num_show = show_foo, plus = undefined }<BR>
<BR>
Of course, I'm glossing over the interesting details of the search,<BR>
but the basic idea is to attempt to fill in the blanks in these<BR>
definitions.<BR>
<BR>
&nbsp; -- ryan<BR>
<BR>
On Wed, May 27, 2009 at 2:10 PM, Paul Keir &lt;pkeir@dcs.gla.ac.uk&gt; wrote:<BR>
&gt; Hi,<BR>
&gt;<BR>
&gt; How does the context of a class instance declaration affect its subclasses?<BR>
&gt;<BR>
&gt; The Num class instance outlined below has its requirement for Eq and Show<BR>
&gt; satisfied on the preceding lines, and the code will compile. But if I, say,<BR>
&gt; add an (Eq a) constraint to the Eq instance, in preparation for a simple<BR>
&gt; (==) definition, I find that the Num instance declaration is left lacking.<BR>
&gt; If I add the same (Eq a) constraint now to Num, calm is restored.<BR>
&gt;<BR>
&gt; data Foo a = F a<BR>
&gt;<BR>
&gt; instance Eq (Foo a) where<BR>
&gt;&nbsp; (==) = undefined<BR>
&gt;<BR>
&gt; instance Show (Foo a) where<BR>
&gt;&nbsp; show = undefined<BR>
&gt;<BR>
&gt; instance Num (Foo a)<BR>
&gt;&nbsp; (+) = undefined<BR>
&gt;&nbsp; ... etc.<BR>
&gt;<BR>
&gt; The thing that confuses me with this is that it seems like Num &quot;knows&quot; that<BR>
&gt; an (Eq a) context has been applied, and so what it sees as a problem, is<BR>
&gt; somehow also the solution. Any advice/rules of thumb? Does this situation<BR>
&gt; occur elsewhere? How do these constraints propagate?<BR>
&gt;<BR>
&gt; Thanks,<BR>
&gt; Paul<BR>
&gt;<BR>
&gt; _______________________________________________<BR>
&gt; Haskell-Cafe mailing list<BR>
&gt; Haskell-Cafe@haskell.org<BR>
&gt; <A HREF="http://www.haskell.org/mailman/listinfo/haskell-cafe">http://www.haskell.org/mailman/listinfo/haskell-cafe</A><BR>
&gt;<BR>
&gt;<BR>
<BR>
<BR>
</FONT>
</P>

</BODY>
</HTML>