<br><br><div class="gmail_quote">On Sat, Jun 27, 2009 at 10:45 PM, Darryn <span dir="ltr">&lt;<a href="mailto:djreid@aapt.net.au">djreid@aapt.net.au</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
Thanks for the help previously received, but I still cannot seem to get<br>
on top of this. The types for the constructor K will not resolve and<br>
I&#39;m at a loss to work out what to do with it. If anyone can offer<br>
a further explanation and help I would be very grateful.<br>
<br>
<br>
My code (File Test5.hs):<br>
----------------------------<br>
{-# LANGUAGE ExistentialQuantification #-}<br>
<div class="im"><br>
class A a where<br>
    a1 :: a<br>
    a2 :: a -&gt; a<br>
    a3 :: (B b) =&gt; b -&gt; a<br>
<br>
class B b where<br>
    b1 :: Int -&gt; b<br>
<br>
</div>--data Ainst b = I | J (Ainst b) | K b<br>
<div class="im">--  a3 :: (B b, A a) =&gt; b -&gt; a<br>
</div>--  yet without the constraint on K, K :: b -&gt; Ainst b<br>
--  so the above data definition fails. Trying to<br>
--  existentially quantify K below seems to make<br>
--  sense, but also fails ...<br>
data Ainst b = I | J (Ainst b) | (B b) =&gt; K b<br>
<div class="im"><br>
instance (B b) =&gt; A (Ainst b) where<br>
    a1 = I<br>
</div>    a2 = J<br>
    a3 = K -- Reported line of the error<br>
<div class="im"><br>
data Binst = Val Int<br>
<br>
instance B Binst where<br>
    b1 = Val<br>
-------------------------------<br>
<br>
</div>The error from ghci is as follows:<br>
<br>
Test5.hs:25:9:<br>
    Couldn&#39;t match expected type `b&#39; against inferred type `b1&#39;<br>
<div class="im">      `b&#39; is a rigid type variable bound by<br>
</div>          the type signature for `a3&#39; at Test5.hs:7:13<br>
<div class="im">      `b1&#39; is a rigid type variable bound by<br>
</div>           the instance declaration at Test5.hs:16:12<br>
<div class="im">      Expected type: b -&gt; Ainst b1<br>
</div>      Inferred type: b1 -&gt; Ainst b1<br>
    In the expression: K<br>
<div class="im">    In the definition of `a3&#39;: a3 = K<br>
</div>Failed, modules loaded: none.<br>
<br>
Thanks in advance for any help. Apologies if what I am doing is odd or<br>
the answer is obvious, I&#39;m still very new to Haskell.<br>
<font color="#888888"></font></blockquote><div><br>The actual problem is not that easy to understand until you really get to know the intricacies of Haskell&#39;s type checking.  Do you think you could explain your problem is less abstract terms?  That is, sometimes if you tell people here what you want to do and why they can suggest a better approach.<br>
<br>One thing to understand about your type class `A&#39; is that it does not give a relationship between `b&#39; and `a&#39;.  As far as the definition of `A&#39; is concerned, `b&#39; is totally arbitrary, so long as it is an instance of `B&#39;.  In particular, no relationship with `a&#39; is implied.  Additionally, I&#39;m nearly certain that existential types are not needed or even wanted here.<br>
<br>K :: b -&gt; Ainst b<br><br>In particular, the `b&#39; that `K&#39; takes becomes part of the type that `K&#39; returns.  This is different than the type of `a3&#39;.  In the type of `a3&#39;, the `b&#39; that it takes doesn&#39;t necessarily become part of the return type.  In a way, that means that `K&#39; is less polymorphic than `a3&#39;.  This may not seem like a problem, but it is what prevents `K&#39; from having the same type as `a3&#39;, and thus you get your error message.  The type of `a3&#39; is more general than the type of `K&#39; due to the possible ranges of the type variables involved.<br>
<br>I have played with it a bit and found that this does compile:<br>\begin{code}<br>{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts #-}<br><br>class A a b | b -&gt; a where<br>
   a1 :: a<br>   a2 :: a -&gt; a<br>   a3 :: (B b) =&gt; b -&gt; a<br><br>class B b where<br>   b1 :: Int -&gt; b<br><br>data Ainst b = I | J (Ainst b) | K b<br><br>instance (B b) =&gt; A (Ainst b) b where<br>   a1 = I<br>
   a2 = J<br>   a3 = K -- Reported line of the error<br><br>data Binst = Val Int<br><br>instance B Binst where<br>   b1 = Val<br>\end{code}<br><br>If you remove all the type class constraints you won&#39;t need the FlexibleContexts, but it&#39;s also not hurting anything.<br>
<br>Here I am using the functional dependency between `a&#39; and `b&#39; that says, once you fix the type of `b&#39;, you also fix the type of `a&#39;.  You&#39;ll notice that, that is exactly what `K&#39; does.  Given a `b&#39;, it gives you `Ainst a&#39;, where `a = b&#39;, and therefore the type depends on, or is fixed by, `b&#39;.  Multi parameter type classes are needed just so we can give the functional dependency and the flexible things are in there just to work around Haskell 98 restrictions.<br>
<br>I hope this sheds more light on the problem.  I bet you could be using type families here as well, but I have yet to take the time to understand them.<br><br>I hope that helps,<br>Jason</div></div><br>