I understand your point Ryan, but in that case, why didn'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>> instance Resource Int where<br>
> type IdOf <b>Int</b> = Int<br>
> type LocOf <b>Int</b> = String<br>
> type CfgOf <b>Int</b> = ()<br>> retrieveLoc () n = "Int_ " ++ show n<br>
> load = undefined<br>> unload = undefined<br><br><br><div class="gmail_quote">2010/11/2 Ryan Ingram <span dir="ltr"><<a href="mailto:ryani.spam@gmail.com">ryani.spam@gmail.com</a>></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>
> -- | Class describing a resource of type @rsc@<br>
> class (Ord (IdOf rsc)) => Resource rsc where<br>
> type IdOf rsc<br>
> type LocOf rsc<br>
> type CfgOf rsc<br>
> retrieveLoc :: CfgOf rsc -> IdOf rsc -> LocOf rsc<br>
> load :: LocOf rsc -> IO (Maybe rsc)<br>
> -- ^ Called when a resource needs to be loaded<br>
> unload :: rsc -> IO ()<br>
> -- ^ 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 = "Unit_" ++ 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 = "Int_ " ++ show n<br>
load = undefined<br>
unload = undefined<br>
<br>
foo = retrieveLoc :: () -> Int -> String -- which retrieveLoc is called here?<br>
<br>
The problem, in case you haven't surmised it, is that retrieveLoc is<br>
ambiguous; you can never call it! There'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>
> data Proxy a = Proxy<br>
> retrieveLoc :: Proxy rsc -> CfgOf rsc -> IdOf rsc -> LocOf rsc<br>
<br>
now:<br>
<br>
> foo = retrieveLoc (Proxy :: Proxy ())<br>
<br>
and ghc can correctly infer foo's type as<br>
> foo :: () -> Int -> String<br>
<br>
and foo will call the retrieveLoc from the () instance.<br>
<font color="#888888"><br>
-- ryan<br>
</font></blockquote></div><br>