<pre><font style="font-family: garamond,serif;" size="2">Hello café,<br><br>I have a little DSL in my program as follow.<br>Now I&#39;d like to add a Map constructor in it. Thats where I would need help!</font><code><span style="font-family: garamond,serif;"><br>
</span><br><span>&gt; data</span> <span>Obs</span> a <span>where</span><br><br>&gt;     <span>AllPlayers</span> :: <span>Obs</span> [<span>Int</span>]<br>&gt;     <span>Plus</span>       :: (<span>Num</span> a) =&gt; <span>Obs</span> a -&gt; <span>Obs</span> a -&gt; <span>Obs</span> a<br>
&gt;     <span>And</span>        :: <span>Obs</span> <span>Bool</span> -&gt; <span>Obs</span> <span>Bool</span> -&gt; <span>Obs</span> <span>Bool</span><br>&gt;     <span>Vote</span>       :: <span>Obs</span> <span>String</span> -&gt; <span>Obs</span> <span>Int</span> -&gt; <span>Obs</span> <span>Bool</span><br>
</code><code>&gt;     <b><span>Map</span>        :: (<span>Obs</span> a -&gt; <span>Obs</span> b) -&gt; <span>Obs</span> [a] -&gt; <span>Obs</span> [b]</b></code><br><code>&gt;     <span>-- and others</span><br><font style="font-family: garamond,serif;" size="2"><br>
Here is the evaluator for Obs:</font><br><br>&gt; evalObs :: <span>Obs</span> a -&gt; <span></span><span>Evaluator</span> a<br>&gt; evalObs (<span>Konst</span> a)   <span>=</span> <span>return</span> <span>$</span> pure a<br>
</code><code>&gt; </code><code>evalObs (<span>Not</span> a)     <span>=</span> liftE  <span>not</span>   (evalObs a)<br></code><code>&gt; </code><code>evalObs (<span>Plus</span> a b)  <span>=</span> liftE2 (<span>+</span>)   (evalObs a) (evalObs b)<br>
</code><code>&gt; </code><code>evalObs (<span>Minus</span> a b) <span>=</span> liftE2 (<span>-</span>)   (evalObs a) (evalObs b)<br></code><code>&gt; </code><code>evalObs (<span>Time</span> a b)  <span>=</span> liftE2 (<span>*</span>)   (evalObs a) (evalObs b)<br>
</code><code>&gt; </code><code>evalObs (<span>And</span> a b)   <span>=</span> liftE2 (<span>&amp;&amp;</span>)  (evalObs a) (evalObs b)<br></code><code>&gt; </code><code>evalObs (<span>Or</span> a b)   <span> =</span> liftE2 (<span>||</span>)  (evalObs a) (evalObs b)<br>
</code><code>&gt; </code><code>evalObs (<span>Equ</span> a b)   <span>=</span> liftE2 (<span>==</span>)  (evalObs a) (evalObs b)<br></code><code>&gt; </code><code>evalObs (<span>If</span> a b c)  <span>=</span> liftE3 (if3) (evalObs a) (evalObs b) (evalObs c)<br>
<font style="font-family: arial,helvetica,sans-serif;" size="2"><br>How you can see it is quite neat...<br>But how can I write the evaluator for Map?<br><br>Actually I have some half baked solution, 15 lines long that I don&#39;t dare to show ;)<br>
<br>Actually compiling code excerpt is here: <a href="http://hpaste.org/40897/map_contstructor_in_a_dsl" target="_blank">http://hpaste.org/40897/map_contstructor_in_a_dsl</a><br><br><br>Thanks for your help.<br></font></code><code><font style="font-family: arial,helvetica,sans-serif;" size="2">Corentin<br>
<br><br>Below is some helper code:</font><br><br><span>type</span> <span>Evaluator</span> a <span>=</span> <span>StateT</span> <span>Game</span> <span>Comm</span> a (<span>Either</span> <span>Actions</span> a)<br><br><br>
<span>-- | Combined lifters for Evaluator</span><br>liftE  <span>=</span> liftM  <span>.</span> liftA<br>liftE2 <span>=</span> liftM2 <span>.</span> liftA2<br>liftE3 <span>=</span> liftM3 <span>.</span> liftA3<br><br></code><code><span></span></code><code><br>
<span>instance</span> <span>Applicative</span> (<span>Either</span> <span>Actions</span>) <span>where</span><br><br>        pure x <span>=</span> <span>Right</span> x<br>        (<span>Right</span> f) <span>&lt;*&gt;</span> (<span>Right</span> x) <span>=</span> <span>Right</span> <span>$</span> f x<br>
<br>        (<span>Right</span> _) <span>&lt;*&gt;</span> (<span>Left</span> u) <span>=</span> <span>Left</span> u<br>        (<span>Left</span> u) <span>&lt;*&gt;</span> (<span>Right</span> _) <span>=</span> <span>Left</span> u<br>
<br>        (<span>Left</span> u) <span>&lt;*&gt;</span> (<span>Left</span> v) <span>=</span> <span>Left</span> <span>$</span> u <span>++</span> v<br><br><br></code></pre>