Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Forwards traveling state with a continuation monad looks like this:</p> <pre><code>Cont (fw -&gt; r) a </code></pre> <p>Then the type of the argument to <code>cont</code> is</p> <pre><code>(a -&gt; fw -&gt; r) -&gt; fw -&gt; r </code></pre> <p>So you get a <code>fw</code> passed in from the past which you have to pass on to the continuation.</p> <p>Backwards traveling state looks like this:</p> <pre><code>Cont (bw, r) a </code></pre> <p>Then the type of the argument to <code>cont</code> is</p> <pre><code>(a -&gt; (bw, r)) -&gt; (bw, r) </code></pre> <p>I.e. you get a <code>bw</code> from the continuation which you have to pass on to the past.</p> <p>These can be combined into one continuation monad:</p> <pre><code>Cont (fw -&gt; (bw, r)) a </code></pre> <p>There's a catch when applying this to your parser, because <code>toProgramStep</code> builds the program in reverse, so the list of ']' points is the forward state, and the list of '[' points is the backward state. Also, I got lazy and skipped the Maybe part, which should catch the pattern matching errors in <code>openBrace</code> and <code>closeBrace</code>.</p> <pre><code>type ParseState = Cont ([TapeP] -&gt; ([TapeP], TapeP)) toProgram :: String -&gt; TapeP toProgram = snd . ($ []) . (`runCont` (\a _ -&gt; ([], a))) . toProgramStep openBrace :: ParseState TapeP -&gt; ParseState TapeP openBrace mcontinue = do continue &lt;- mcontinue cont $ \k (break:bs) -&gt; let (cs, r) = k (loopControl continue break) bs in (continue:cs, r) closeBrace :: ParseState TapeP -&gt; ParseState TapeP closeBrace mbreak = do break &lt;- mbreak cont $ \k bs -&gt; let (continue:cs, r) = k (loopControl continue break) (break:bs) in (cs, r) </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload