Just write a loop:<br><br>&gt; let loop gs gu<br>&gt;    | Just z &lt;- find_obj gu usyms = do<br>&gt;            ...<br>&gt;            (gs&#39;, gu&#39;) &lt;- handle_obj_ar ...<br>&gt;            loop gs&#39; gu&#39;<br>
&gt;    | otherwise = return (gs,gu)<br>&gt; (gs, gu) &lt;- loop def undef<br><br>mfix is for when you have mutually recursive data but you want the IO operation to only execute once.  It&#39;s most useful when working with some sort of lazy data structure like a list, tree, or graph.<br>
<br>I can&#39;t come up with an example for IO off the top of my head, but for the ICFP contest this year I wrote a gate/wire embedded language which had code that looks like this:<br><br>sample wireIn = do<br>    rec<br>
        (wireOut,a) &lt;- gate (wireIn,d)<br>        (d,b) &lt;- gate (a, b)<br>    return wireOut<br><br>which would create a circuit like this:<br><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> ---in-&gt;[  ]------out--------&gt;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">  +-d-&gt;[  ]--a--&gt;[  ]-d---+<br>  |         +-b-&gt;[  ]-b-+ |<br>  |         +-----------+ |<br>  +-----------------------+<br></span><br>This code translates to something like<br>
<br>sample wireIn = do<br>    (wireOut, _, _, _) &lt;- mfix $ \(_, b, d) -&gt; do<br>        (wireOut&#39;, a) &lt;- gate (wireIn, d)<br>        (d&#39;, b&#39;) &lt;- gate (a,b)<br>        return (wireOut&#39;, b&#39;, d&#39;)<br>
    return wireOut&#39;<br><br>The key is that gate was lazy in its arguments; the gate didn&#39;t care what its input wires were, it just needed them to exist at the time you asked for the entire circuit definition.  mfix says &#39;run the *effects* in this code once, but the *data* might be recursive&#39;.<br>
<br>  -- ryan<br><br>