Hmm, I don&#39;t understand how that would work.<div><br><div><br></div><div>I wish I could define something like this:<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>class (Functor f) =&gt; Fixpoint f x | x -&gt; f where</div>

</div><div><div>    fix :: x -&gt; Fix f</div></div><div><div><br></div></div><div><div>instance (Functor f) =&gt; Fixpoint f (forall a. f a) where</div></div><div><div>    fix = id</div></div><div><div><br></div></div><div>

<div>instance (Functor f, Fixpoint f x) =&gt; Fixpoint f (f x) where</div></div><div><div>    fix = Fix . fmap fix</div></div></blockquote><div><div><br></div><div>but instances with polymorphic types aren&#39;t allowed. (Why is that?)</div>

<div><br></div><div><br></div><div>Alternatively if I could write a function that could turn</div></div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span style>e :: forall a. F (F (F ... (F a) ... ))</span></div>

</div></blockquote><font color="#222222" face="arial, sans-serif"><div><font color="#222222" face="arial, sans-serif"><br></font></div>into</font></div><div><font color="#222222" face="arial, sans-serif"><br></font><blockquote style="margin:0 0 0 40px;border:none;padding:0px">

<div><font color="#222222" face="arial, sans-serif">specialize e :: F (F (F ... (F X) ... ))</font></div></blockquote><div><div><br></div><div>that would work too, but I don&#39;t see how that&#39;s possible.</div><div><br>

<div class="gmail_quote">On Mon, May 7, 2012 at 6:59 PM, wren ng thornton <span dir="ltr">&lt;<a href="mailto:wren@freegeek.org" target="_blank">wren@freegeek.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">On 5/7/12 8:55 PM, Sebastien Zany wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
To slightly alter the question, is there a way to define a class<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
class (Functor f) =&gt;  Fixpoint f x where<br>
     ...<br>
</blockquote></blockquote>
<br></div>
You can just do that (with MPTCs enabled). Though the usability will be much better if you use fundeps or associated types in order to constrain the relation between fs and xs. E.g.:<br>
<br>
    -- All the following require the laws:<br>
    -- &gt; fix . unfix == id<br>
    -- &gt; unfix . fix == id<br>
<br>
    -- With MPTCs and fundeps:<br>
    class (Functor f) =&gt; Fixpoint f x | f -&gt; x where<br>
        fix   :: f x -&gt; x<br>
        unfix :: x -&gt; f x<br>
<br>
    class (Functor f) =&gt; Fixpoint f x | x -&gt; f where<br>
        fix   :: f x -&gt; x<br>
        unfix :: x -&gt; f x<br>
<br>
    class (Functor f) =&gt; Fixpoint f x | f -&gt; x, x -&gt; f where<br>
        fix   :: f x -&gt; x<br>
        unfix :: x -&gt; f x<br>
<br>
    -- With associated types:<br>
    -- (Add a type/data family if you want both Fix and Pre.)<br>
    class (Functor f) =&gt; Fixpoint f where<br>
        type Fix f :: *<br>
        fix   :: f (Fix f) -&gt; Fix f<br>
        unfix :: Fix f -&gt; f (Fix f)<br>
<br>
    class (Functor f) =&gt; Fixpoint f where<br>
        data Fix f :: *<br>
        fix   :: f (Fix f) -&gt; Fix f<br>
        unfix :: Fix f -&gt; f (Fix f)<br>
<br>
    class (Functor (Pre x)) =&gt; Fixpoint x where<br>
        type Pre x :: * -&gt; *<br>
        fix   :: Pre x x -&gt; x<br>
        unfix :: x -&gt; Pre x x<br>
<br>
    class (Functor (Pre x)) =&gt; Fixpoint x where<br>
        data Pre x :: * -&gt; *<br>
        fix   :: Pre x x -&gt; x<br>
        unfix :: x -&gt; Pre x x<br>
<br>
Indeed, that last one is already provided in the fixpoint[1] package, though the names are slightly different. The differences between using &quot;x -&gt; f&quot;, &quot;f -&gt; x&quot;, or both, and between using &quot;data&quot; or &quot;type&quot;, are how it affects inference. That is, implicitly there are two relations on types:<br>


<br>
    Fix \subseteq * \cross *<br>
    Pre \subseteq * \cross *<br>
<br>
And we need to know: (1) are these relations functional or not? And, (2) are they injective or not? The answers to those questions will affect how you can infer one of the types (f or x) given the other (x or f).<br>
<br>
<br>
[1] <a href="http://hackage.haskell.org/package/fixpoint" target="_blank">http://hackage.haskell.org/<u></u>package/fixpoint</a><div class="HOEnZb"><div class="h5"><br>
<br>
-- <br>
Live well,<br>
~wren<br>
<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br></div></div></div></div>