Free Monads. It's amazing to be confronted again with notions I learned 
more than ten years ago for groups. I have to admit that I'm probably 
not yet prepared for a deeper understanding of this, but hopefully I 
will return to it later ;-)<br>
Is Cont free as well? I guess so because I heard it&#39;s sometimes called the mother of all monads.<br><br>Regards<br>Tim<br><br><div class="gmail_quote">2011/11/21 David Menendez <span dir="ltr">&lt;<a href="mailto:dave@zednenem.com">dave@zednenem.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">On Sat, Nov 19, 2011 at 3:29 PM, Felipe Almeida Lessa<br>
&lt;<a href="mailto:felipe.lessa@gmail.com">felipe.lessa@gmail.com</a>&gt; wrote:<br>
&gt; On Sat, Nov 19, 2011 at 6:08 PM, Tim Baumgartner<br>
&gt; &lt;<a href="mailto:baumgartner.tim@googlemail.com">baumgartner.tim@googlemail.com</a>&gt; wrote:<br>
&gt;&gt; I have not yet gained a good understanding of the continuation monad, but I<br>
&gt;&gt; wonder if it could be used here. What would a clean solution look like?<br>
&gt;&gt; Perhaps there are other things that need to be changed as well?<br>
&gt;<br>
&gt; Your &#39;Interaction&#39; data type is actually an instance of the more<br>
&gt; general &quot;operational monad&quot; (as named by Heinrich Apfelmus) or &quot;prompt<br>
&gt; monad&quot; (as named by Ryan Ingram).<br>
<br>
</div>Both of which are just disguised free monads. For reference:<br>
<br>
<br>
data Free f a = Val a | Wrap (f (Free f a))<br>
<br>
foldFree :: Functor f =&gt; (a -&gt; b) -&gt; (f b -&gt; b) -&gt; Free f a -&gt; b<br>
foldFree v w (Val a)  = v a<br>
foldFree v w (Wrap t) = w $ fmap (foldFree v w) t<br>
<br>
instance Functor f =&gt; Monad (Free f) where<br>
        return  = Val<br>
        m &gt;&gt;= f = foldFree f Wrap m<br>
<br>
<br>
<br>
To use Free, just find the signature functor for Interaction by<br>
replacing the recursive instances with a new type variable,<br>
<br>
data InteractionF a b x = ExitF b<br>
                        | OutputF b x<br>
                        | InputF (a -&gt; x)<br>
<br>
instance Functor (InteractionF a b) where<br>
        fmap f (ExitF b)     = ExitF b<br>
        fmap f (OutputF b x) = OutputF b (f x)<br>
        fmap f (InputF g)    = InputF (f . g)<br>
<br>
roll :: InteractionF a b (Interaction a b) -&gt; Interaction a b<br>
roll (ExitF b)     = Exit b<br>
roll (OutputF b x) = Output b x<br>
roll (InputF g)    = Input g<br>
<br>
<br>
type InteractionM a b = Free (InteractionF a b)<br>
<br>
runM :: InteractionM a b b -&gt; Interaction a b<br>
runM = foldFree Exit roll<br>
<br>
exit :: b -&gt; InteractionM a b c<br>
exit b = Wrap (ExitF b)<br>
<br>
output :: b -&gt; InteractionM a b ()<br>
output b = Wrap (OutputF b (Val ()))<br>
<br>
input :: InteractionM a b a<br>
input = Wrap (InputF Val)<br>
<font color="#888888"><br>
--<br>
Dave Menendez &lt;<a href="mailto:dave@zednenem.com">dave@zednenem.com</a>&gt;<br>
&lt;<a href="http://www.eyrie.org/%7Ezednenem/" target="_blank">http://www.eyrie.org/~zednenem/</a>&gt;<br>
</font></blockquote></div><br>