<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'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>> data</span> <span>Obs</span> a <span>where</span><br><br>> <span>AllPlayers</span> :: <span>Obs</span> [<span>Int</span>]<br>> <span>Plus</span> :: (<span>Num</span> a) => <span>Obs</span> a -> <span>Obs</span> a -> <span>Obs</span> a<br>
> <span>And</span> :: <span>Obs</span> <span>Bool</span> -> <span>Obs</span> <span>Bool</span> -> <span>Obs</span> <span>Bool</span><br>> <span>Vote</span> :: <span>Obs</span> <span>String</span> -> <span>Obs</span> <span>Int</span> -> <span>Obs</span> <span>Bool</span><br>
</code><code>> <b><span>Map</span> :: (<span>Obs</span> a -> <span>Obs</span> b) -> <span>Obs</span> [a] -> <span>Obs</span> [b]</b></code><br><code>> <span>-- and others</span><br><font style="font-family: garamond,serif;" size="2"><br>
Here is the evaluator for Obs:</font><br><br>> evalObs :: <span>Obs</span> a -> <span></span><span>Evaluator</span> a<br>> evalObs (<span>Konst</span> a) <span>=</span> <span>return</span> <span>$</span> pure a<br>
</code><code>> </code><code>evalObs (<span>Not</span> a) <span>=</span> liftE <span>not</span> (evalObs a)<br></code><code>> </code><code>evalObs (<span>Plus</span> a b) <span>=</span> liftE2 (<span>+</span>) (evalObs a) (evalObs b)<br>
</code><code>> </code><code>evalObs (<span>Minus</span> a b) <span>=</span> liftE2 (<span>-</span>) (evalObs a) (evalObs b)<br></code><code>> </code><code>evalObs (<span>Time</span> a b) <span>=</span> liftE2 (<span>*</span>) (evalObs a) (evalObs b)<br>
</code><code>> </code><code>evalObs (<span>And</span> a b) <span>=</span> liftE2 (<span>&&</span>) (evalObs a) (evalObs b)<br></code><code>> </code><code>evalObs (<span>Or</span> a b) <span> =</span> liftE2 (<span>||</span>) (evalObs a) (evalObs b)<br>
</code><code>> </code><code>evalObs (<span>Equ</span> a b) <span>=</span> liftE2 (<span>==</span>) (evalObs a) (evalObs b)<br></code><code>> </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'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><*></span> (<span>Right</span> x) <span>=</span> <span>Right</span> <span>$</span> f x<br>
<br> (<span>Right</span> _) <span><*></span> (<span>Left</span> u) <span>=</span> <span>Left</span> u<br> (<span>Left</span> u) <span><*></span> (<span>Right</span> _) <span>=</span> <span>Left</span> u<br>
<br> (<span>Left</span> u) <span><*></span> (<span>Left</span> v) <span>=</span> <span>Left</span> <span>$</span> u <span>++</span> v<br><br><br></code></pre>