To slightly alter the question, is there a way to define a class<div><div><br></div><div>&gt; class (Functor f) =&gt; Fixpoint f x where</div><div>&gt;     ...</div><div><br></div><div>so that I can define something with a type signature that looks like</div>

<div><br></div><div>&gt; something :: (Fixpoint f x) =&gt; ... x ...</div><div><br></div><div>which will accept any</div><div><br></div><div>&gt; argument :: F (F (F ... (F a) ... ))</div><div><br></div><div>in place of x?</div>

<div><br></div><div>Or alternatively could something analogous be done with type families?</div><div><br></div><div>Thanks,</div><div>Sebastien</div><div><br><div class="gmail_quote">On Mon, May 7, 2012 at 5:45 PM, Sebastien Zany <span dir="ltr">&lt;<a href="mailto:sebastien@chaoticresearch.com" target="_blank">sebastien@chaoticresearch.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks Wren!<div><br></div><div>When I try</div><div>&gt; fix term</div><div>ghci complains of an ambiguous type variable.</div>

<div><br></div><div>I have to specify</div><div>&gt; term :: (Expr (Expr (Expr (Fix Expr))))</div>

<div>for it to work.</div><div><br></div><div>Is there a way around this?</div><div class="HOEnZb"><div class="h5"><div><br><div class="gmail_quote">On Sun, May 6, 2012 at 4:04 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><div>On 5/6/12 8:59 AM, Sebastien Zany wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi,<br>
<br>
Suppose I have the following types:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
data Expr expr = Lit Nat | Add (expr, expr)<br>
newtype Fix f = Fix {unFix :: f (Fix f)}<br>
</blockquote>
<br>
I can construct a sample term:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
term :: Expr (Expr (Expr expr))<br>
term = Add (Lit 1, Add (Lit 2, Lit 3))<br>
</blockquote>
<br>
But isn&#39;t quite what I need. What I really need is:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
term&#39; :: Fix Expr<br>
term&#39; = Fix . Add $ (Fix . Lit $ 1, Fix . Add $ (Fix . Lit $ 2, Fix . Lit<br>
</blockquote>
$ 3))<br>
<br>
I feel like there&#39;s a stupidly simple way to automatically produce term&#39;<br>
from term, but I&#39;m not seeing it.<br>
</blockquote>
<br></div></div>
There&#39;s the smart constructors approach to building term&#39; in the first place, but if someone else is giving you the term and you need to convert it, then you&#39;ll need to use a catamorphism (or similar).<br>
<br>
That is, we already have:<br>
<br>
    Fix :: Expr (Fix Expr) -&gt; Fix Expr<br>
<br>
but we need to plumb this down through multiple layers:<br>
<br>
    fmap Fix :: Expr (Expr (Fix Expr)) -&gt; Expr (Fix Expr)<br>
<br>
    fmap (fmap Fix) :: Expr (Expr (Expr (Fix Expr)))<br>
                    -&gt; Expr (Expr (Fix Expr))<br>
<br>
    ...<br>
<br>
If you don&#39;t know how many times the incoming term has been unFixed, then you&#39;ll need a type class to abstract over the n in fmap^n Fix. How exactly you want to do that will depend on the application, how general it should be, etc. The problem, of course, is that we don&#39;t have functor composition for free in Haskell. Francesco&#39;s suggestion is probably the easiest:<br>




<br>
    instance Functor Expr where<br>
        fmap _ (Lit i)     = Lit i<br>
        fmap f (Add e1 e2) = Add (f e1) (f e2)<br>
<br>
    class FixExpr e where<br>
        fix :: e -&gt; Fix Expr<br>
<br>
    instance FixExpr (Fix Expr) where<br>
        fix = id<br>
<br>
    instance FixExpr e =&gt; FixExpr (Expr e) where<br>
        fix = Fix . fmap fix<br>
<br>
Note that the general form of catamorphisms is:<br>
<br>
    cata :: Functor f =&gt; (f a -&gt; a) -&gt; Fix f -&gt; a<br>
    cata f = f . fmap (cata f) . unFix<br>
<br>
so we&#39;re just defining fix = cata Fix, but using induction on the type term itself (via type classes) rather than doing induction on the value term like we usually would.<span><font color="#888888"><br>

<br>
-- <br>
Live well,<br>
~wren</font></span><div><div><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></blockquote></div><br></div></div>