Dear cafe,<br>Recently, I decided to use Haskell to drive the testing of a C++ DLL that we develop. After getting the FFI etc working, I thought it might be a good idea to expose an EDSL for the testers to alter the flow of invocations of the functions in the DLL. I&#39;ve tried to demonstrate the approach I am contemplating here - <a href="http://hpaste.org/67495">http://hpaste.org/67495</a><br>
<br>The outcome is that I&#39;ll have a set of &quot;Instructions&quot; for the testers can arrange to create a sequence of calls. <br><br>&gt; data Command = Void | Init | Get3Numbers Int Int Int| GetName String | PrintName | PrintSum | Close | PrintMessage String<br>
&gt;     deriving (Show)<br><br>&gt; mainloop :: StateT (ScriptState Command) IO ()<br>&gt; mainloop = do<br>&gt;         liftIO $ putStrLn &quot;Hello World&quot;<br>&gt;         executeCommand Init<br>&gt;         executeCommand Init<br>
&gt;         executeCommand $ PrintMessage &quot;Enter name&quot;<br>&gt;         executeCommand $ GetName &quot;abcd&quot;<br>&gt;         return ()<br><br><br>I&#39;d like to ensure that some level of validation done. For example, if Init is called twice, the tester should get to know about it. Similarly, GeName should not be called unless PrintMessage has been called.<br>
<br>&gt; executeCommand :: Command -&gt; StateT (ScriptState Command) IO ()<br>&gt; executeCommand Init = do<br>&gt;                (ScriptState c) &lt;- get<br>&gt;                case c of<br>&gt;                     Void -&gt; liftIO $ putStrLn (show c)<br>
&gt;                     _    -&gt; liftIO $ putStrLn &quot;Init already called&quot;<br>&gt;                put (ScriptState Init)<br>&gt;                return ()<br>&gt; executeCommand (GetName x) = do<br>&gt;                (ScriptState c) &lt;- get<br>
&gt;                case c of<br>&gt;                     PrintMessage _ -&gt; do { str &lt;- liftIO $ getLine; put (ScriptState (GetName str)); return ()}<br>&gt;                     _              -&gt; liftIO $ putStrLn &quot;PrintMessage not called&quot;<br>
&gt; executeCommand (PrintMessage m) = do<br>&gt;                liftIO $ putStrLn m<br>&gt;                put (ScriptState (PrintMessage m))<br><br><br>I&#39;d appreciate it very much if you could give me some feedback on my 
approach. I get this feeling that I am wrapping up the whole program 
inside a State monad - does this mean that I am giving up the functional
 goodies.<br>
<br>Regards,<br>Kashyap<br>