Thanks Ryan.<div><br></div><div>I&#39;m always struggling with functional dependencies since to be honest - I don&#39;t really understand how the type inferer figures out all the types and I didn&#39;t take the time to study it yet. Your email will help me a bit further with this.</div>
<div><br></div><div>My functional dependency was c -&gt; m v. It can&#39;t be m v -&gt; c since for the same model and view type , you can have many controllers types.</div><div><br></div><div><div class="gmail_quote">On Sat, Feb 14, 2009 at 11:38 PM, Ryan Ingram <span dir="ltr">&lt;<a href="mailto:ryani.spam@gmail.com">ryani.spam@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">2009/2/13 Peter Verswyvelen &lt;<a href="mailto:bugfact@gmail.com">bugfact@gmail.com</a>&gt;:<br>
<div class="Ih2E3d">&gt; No the error I got was<br>
&gt; Could not deduce (Controller m v c)<br>
&gt; from the context (Controller m v c2)<br>
&gt; &nbsp; &nbsp; &nbsp; arising from a use of `MVC&#39; at NM8\GUI\PanZoom.hs:126:32-65<br>
&gt; &nbsp; &nbsp; Possible fix:<br>
&gt; &nbsp; &nbsp; &nbsp; add (Controller m v c) to the context of the constructor `MVC&#39;<br>
&gt; &nbsp; &nbsp; In the expression: MVC m v (PZC s z (unsafeCoerce c))<br>
&gt; &nbsp; &nbsp; In the definition of `panZoomedMVC&#39;&#39;:<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; panZoomedMVC&#39; s z (MVC m v c) = MVC m v (PZC s z (unsafeCoerce c))<br>
&gt; I got this after adding the type signature of<br>
&gt; panZoomedMVC&#39; :: (Controller m v c, PanZoomable z) =&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;State -&gt; z -&gt; MVC m v -&gt; MVC m v<br>
<br>
</div>No function with the type signature of panZoomedMVC&#39; can be called<br>
(unless there is a functional dependency that uniquely determines c<br>
from m and v). &nbsp;It&#39;s ambiguous; there&#39;s no way to know which instance<br>
to call.<br>
<br>
GHC allows such a function to get an inferred type, but then when it<br>
comes time to call it (and provide the Controller instance) or type<br>
check it against a provided signature, it cannot resolve the ambiguity<br>
and you get that error.<br>
<br>
What is happening in this case is something along these lines:<br>
<br>
1) Infer a type and constraints for panZoomedMVC&#39;:<br>
<br>
Constraints:<br>
 &nbsp; Controller t1 t2 t3<br>
 &nbsp; PanZoomable t4<br>
<br>
Type:<br>
 &nbsp; State -&gt; t4 -&gt; MVC t1 t2 -&gt; MVC t1 t2<br>
<br>
2) Unify the inferred type signature with your provided signature<br>
<br>
Constraints:<br>
 &nbsp; Controller m v t3<br>
 &nbsp; PanZoomable z<br>
<br>
Type:<br>
<div class="Ih2E3d"> &nbsp; State -&gt; z -&gt; MVC m v -&gt; MVC m v<br>
<br>
</div>3) Verify that constraints are sufficient. &nbsp;This fails, because the<br>
use of Controller in the function (Controller m v t3) doesn&#39;t match<br>
the use provided by your constraint (Controller m v c).<br>
<br>
However, leaving out the type signature doesn&#39;t help you; it just<br>
delays your problem. &nbsp;Because of the ambiguity, panZoomedMVC&#39; cannot<br>
be called; you&#39;ll get the error at the callsite instead.<br>
<br>
To solve this problem, either add a dummy argument that fixes &quot;c&quot;, or<br>
add a functional dependency or associated type to Controller that<br>
fixes c based on m and v. &nbsp;For example:<br>
<br>
&gt; data Proxy a = Proxy<br>
<div class="Ih2E3d">&gt; panZoomedMVC&#39; :: (Controller m v c, PanZoomable z) =&gt;<br>
</div>&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Proxy c -&gt; State -&gt; z -&gt; MVC m v -&gt; MVC m v<br>
&gt; panZoomedMVC&#39; _ s z mvc = ...<br>
<br>
Then you can pass the proper &quot;Proxy&quot; when calling the function to make<br>
the typechecker happy.<br>
<br>
or<br>
<br>
&gt; class Controller m v c | m v -&gt; c where ...<br>
<br>
or<br>
<br>
&gt; class Controller m v where<br>
&gt; &nbsp; &nbsp;type Control m v<br>
&gt; &nbsp; &nbsp;...<br>
<font color="#888888"><br>
 &nbsp;-- ryan<br>
</font></blockquote></div><br></div>