I understand your point Ryan, but in that case, why didn&#39;t the error occur when Resource and ResourceId were separated classes?<br><br>BTW, I assume for your Int instance of Resource, you meant:<br>&gt; instance Resource Int where<br>

 &gt;   type IdOf <b>Int</b> = Int<br>
 &gt;   type LocOf <b>Int</b> = String<br>
 &gt;   type CfgOf <b>Int</b> = ()<br>&gt;   retrieveLoc () n = &quot;Int_ &quot; ++ show n<br>
 &gt;   load = undefined<br>&gt;   unload = undefined<br><br><br><div class="gmail_quote">2010/11/2 Ryan Ingram <span dir="ltr">&lt;<a href="mailto:ryani.spam@gmail.com">ryani.spam@gmail.com</a>&gt;</span><br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
This one is easy:<br>
<div class="im"><br>
&gt; -- | Class describing a resource of type @rsc@<br>
&gt; class (Ord (IdOf rsc)) =&gt; Resource rsc where<br>
&gt;   type IdOf rsc<br>
&gt;   type LocOf rsc<br>
&gt;   type CfgOf rsc<br>
&gt;   retrieveLoc :: CfgOf rsc -&gt; IdOf rsc -&gt; LocOf rsc<br>
&gt;   load   :: LocOf rsc -&gt; IO (Maybe rsc)<br>
&gt;     -- ^ Called when a resource needs to be loaded<br>
&gt;   unload :: rsc -&gt; IO ()<br>
&gt;     -- ^ Idem for unloading<br>
<br>
</div>Consider this:<br>
<br>
instance Resource () where<br>
   type IdOf () = Int<br>
   type LocOf () = String<br>
   type CfgOf () = ()<br>
   retrieveLoc () n = &quot;Unit_&quot; ++ show n<br>
   load = undefined<br>
   unload = undefined<br>
<br>
instance Resource Int where<br>
   type IdOf () = Int<br>
   type LocOf () = String<br>
   type CfgOf () = ()<br>
   retrieveLoc () n = &quot;Int_ &quot; ++ show n<br>
   load = undefined<br>
   unload = undefined<br>
<br>
foo = retrieveLoc :: () -&gt; Int -&gt; String  -- which retrieveLoc is called here?<br>
<br>
The problem, in case you haven&#39;t surmised it, is that retrieveLoc is<br>
ambiguous; you can never call it!  There&#39;s no way to know which<br>
instance you might be referring to.  You can work around it by making<br>
one of the type families into a data family (which is injective; you<br>
know that if CfgOf x = CfgOf y, then x = y).  Or you can add a proxy<br>
parameter to retrieveLoc:<br>
<br>
&gt; data Proxy a = Proxy<br>
&gt; retrieveLoc :: Proxy rsc -&gt; CfgOf rsc -&gt; IdOf rsc -&gt; LocOf rsc<br>
<br>
now:<br>
<br>
&gt; foo = retrieveLoc (Proxy :: Proxy ())<br>
<br>
and ghc can correctly infer foo&#39;s type as<br>
&gt; foo :: () -&gt; Int -&gt; String<br>
<br>
and foo will call the retrieveLoc from the () instance.<br>
<font color="#888888"><br>
  -- ryan<br>
</font></blockquote></div><br>