You might also look at doing it without all the State monad noise with something like:<div><br></div><div><div>&gt; class Symantics repr  where</div><div>&gt;    int :: Int  -&gt; repr Int</div><div>&gt;    add :: repr Int  -&gt; repr Int -&gt; repr Int</div>
<div>&gt;    lam :: (repr a -&gt; repr b) -&gt; repr (a-&gt;b)</div><div>&gt;    app :: repr (a -&gt; b) -&gt; repr a -&gt; repr b</div><div><br></div><div>&gt; newtype Pretty a = Pretty { runPretty :: [String] -&gt; String } </div>
<div><br></div><div>&gt; pretty :: Pretty a -&gt; String</div><div>&gt; pretty (Pretty f) = f vars where</div><div>&gt;     vars = [ [i] | i &lt;- [&#39;a&#39;..&#39;z&#39;]] ++ [i : show j | j &lt;- [1..], i &lt;- [&#39;a&#39;..&#39;z&#39;] ]</div>
<div><br></div><div>&gt; instance Symantics Pretty where</div><div>&gt;    int = Pretty . const . show</div><div>&gt;    add x y = Pretty $ \vars -&gt; &quot;(&quot; ++ runPretty x vars ++ &quot; + &quot; ++ runPretty y vars ++ &quot;)&quot;</div>
<div>&gt;    lam f = Pretty $ \ (v:vars) -&gt; &quot;(\\&quot; ++ v ++ &quot;. &quot; ++ runPretty (f (var v)) vars ++ &quot;)&quot; where</div><div>&gt;        var = Pretty . const</div><div>&gt;    app f x = Pretty $ \vars -&gt; &quot;(&quot; ++ runPretty f vars ++ &quot; &quot; ++ runPretty x vars ++ &quot;)&quot;</div>
<div><br></div><div>-Edward Kmett</div><div><br><div class="gmail_quote">On Thu, Jul 2, 2009 at 5:52 PM, Kim-Ee Yeoh <span dir="ltr">&lt;<a href="mailto:a.biurvOir4@asuhan.com">a.biurvOir4@asuhan.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><br>
I&#39;m trying to write HOAS Show instances for the finally-tagless<br>
type-classes using actual State monads.<br>
<br>
The original code:<br>
<a href="http://okmij.org/ftp/Computation/FLOLAC/EvalTaglessF.hs" target="_blank">http://okmij.org/ftp/Computation/FLOLAC/EvalTaglessF.hs</a><br>
<br>
Two type variables are needed: one to vary over the Symantics<br>
class (but only as a phantom type) and another to vary over the<br>
Monad class. Hence, the use of 2-variable type constructors.<br>
<br>
&gt; type VarCount = int<br>
&gt; newtype Y b a = Y {unY :: VarCount -&gt; (b, VarCount)}<br>
<br>
Not knowing of a type-level &#39;flip&#39;, I resort to newtype isomorphisms:<br>
<br>
&gt; newtype Z a b = Z {unZ :: Y b a}<br>
&gt; instance Monad (Z a)  where<br>
&gt;    return x         = Z $ Y $ \c  -&gt; (x,c)<br>
&gt;    (Z (Y m)) &gt;&gt;= f  = Z $ Y $ \c0 -&gt; let (x,c1) = m c0 in (unY . unZ) (f<br>
&gt; x) c1        -- Pace, too-strict puritans<br>
&gt; instance MonadState String (Z a)  where<br>
&gt;    get   = Z $ Y $ \c -&gt; (show c, c)<br>
&gt;    put x = Z $ Y $ \_ -&gt; ((), read x)<br>
<br>
So far so good.  Now for the Symantics instances (abridged).<br>
<br>
&gt; class Symantics repr  where<br>
&gt;    int  :: Int  -&gt; repr Int              -- int literal<br>
&gt;    add :: repr Int  -&gt; repr Int -&gt; repr Int<br>
&gt;    lam :: (repr a -&gt; repr b) -&gt; repr (a-&gt;b)<br>
<br>
&gt; instance Symantics (Y String)  where<br>
&gt;    int     = unZ . return . show<br>
&gt;    add x y = unZ $ do<br>
&gt;       sx &lt;- Z x<br>
&gt;       sy &lt;- Z y<br>
&gt;       return $ &quot;(&quot; ++ sx ++ &quot; + &quot; ++ sy ++ &quot;)&quot;<br>
<br>
The add function illustrates the kind of do-sugaring we know and love<br>
that I want to use for Symantics.<br>
<br>
&gt;    lam f   = unZ $ do<br>
&gt;       show_c0 &lt;- get<br>
&gt;       let<br>
&gt;          vname = &quot;v&quot; ++ show_c0<br>
&gt;          c0 = read show_c0 :: VarCount<br>
&gt;          c1 = succ c0<br>
&gt;          fz :: Z a String -&gt; Z b String<br>
&gt;          fz = Z . f . unZ<br>
&gt;       put (show c1)<br>
&gt;       s &lt;- (fz . return) vname<br>
&gt;       return $ &quot;(\\&quot; ++ vname ++ &quot; -&gt; &quot; ++ s ++ &quot;)&quot;<br>
<br>
Now with lam, I get this cryptic error message (under 6.8.2):<br>
<br>
    Occurs check: cannot construct the infinite type: b = a -&gt; b<br>
    When trying to generalise the type inferred for `lam&#39;<br>
      Signature type:     forall a1 b1.<br>
                          (Y String a1 -&gt; Y String b1) -&gt; Y String (a1 -&gt;<br>
b1)<br>
      Type to generalise: forall a1 b1.<br>
                          (Y String a1 -&gt; Y String b1) -&gt; Y String (a1 -&gt;<br>
b1)<br>
    In the instance declaration for `Symantics (Y String)&#39;<br>
<br>
Both the two types in the error message are identical, which suggests<br>
no generalization is needed.  I&#39;m puzzled why ghc sees an infinite type.<br>
<br>
Any ideas on how to proceed?<br>
<font color="#888888"><br>
--<br>
View this message in context: <a href="http://www.nabble.com/Flipping-*-%3E*-%3E*-kinds%2C-or-monadic-finally-tagless-madness-tp24314553p24314553.html" target="_blank">http://www.nabble.com/Flipping-*-%3E*-%3E*-kinds%2C-or-monadic-finally-tagless-madness-tp24314553p24314553.html</a><br>

Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</font></blockquote></div><br></div></div>