<div>Hello Henry,</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
But I guess you are not asking about advantages/disadvantages, but how the hell it works ;-)
</blockquote><div><br></div><div>Yes, the first thing I want to know is how it works?</div><div><br></div><div>
<div>thank you very much for your example. It has helped me a lot to begin with.<br></div><div>You have simplified the general DFA problem to a specific one.</div><br></div><div>Your example seems more helpful to me, but can you please remove the IO stuff from your first (non-state monadic) example and repost the same example again?</div>
<div><br></div><div>More specifically, I want to see a definition like:</div><div><font face="courier new,monospace"> mystatemachine :: String -> String</font></div><div>in the first example too.</div><div><br></div>
<div>The IO stuff is adding to my confusion as I am unable to compare the exact difference between the two examples. I could remove the IO part from the second example very easily by directly executing the function "<font face="courier new,monospace">mystatemachine" </font>at the GHCi prompt.</div>
<div><br></div><div>The IO stuff more scarier for me. Till now I have not used any IO in Haskell. I think, if I cannot use State Monad then I cannot use the more scarier IO monad.</div><div><br></div><div>Thanks again for the help.<br>
</div><div>kak</div><div><br></div><div class="gmail_quote">On Wed, May 30, 2012 at 8:44 PM, Henry Lockyer <span dir="ltr"><<a href="mailto:henry.lockyer@ntlworld.com" target="_blank">henry.lockyer@ntlworld.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>I should have gone back and cleaned up my original 'Version 1' example so that both examples use exactly the same 'stateMC' function.</div>
<div>I have now made this small improvement below FWIW. </div><div>/Henry</div><br><div><div><div class="h5"><div>On 30 May 2012, at 15:31, Henry Lockyer wrote:</div><br><blockquote type="cite"><div style="word-wrap:break-word">
<div>Hi kak,</div><div><br></div><div><div>On 28 May 2012, at 19:49, kak dod wrote:</div><br><blockquote type="cite"><div>Hello,<br></div><div>A very good morning to all.</div><div><br></div><div>I am a Haskell beginner. And although I have written fairly complicated programs and have understood to some extent the concepts like pattern matching, folds, scans, list comprehensions, but I have not satisfactorily understood the concept of Monads yet. I have partially understood
and used the Writer, List and Maybe monads but the State monad completely baffles me.</div><div><br></div><div>I wanted to write a program
for the following problem: A DFA simulator. This I guess is a right candidate for State monad as it
mainly
deals with state changes.</div><div><br></div><div>What the program is supposed to do is:</div></blockquote><br><blockquote type="cite"><div>. . . </div></blockquote><br><blockquote type="cite"><div style="margin-left:0px!important">
I wrote a recursive program to do this without using any monads. I simply send the entire dfa, the input string and its partial result in the recursive calls.</div><div style="margin-left:0px!important"><br></div><div style="margin-left:0px!important">
How to do this using State Monad?</div><div style="margin-left:0px!important"><br></div><div style="margin-left:0px!important">. . .</div><div style="margin-left:0px!important"><br></div><div style="margin-left:0px!important">
Please note that I wish your solution to use the <code>Control.Monad.State. </code></div></blockquote></div><br><div>I coincidentally included something like this in another post I recently made. </div><div>I have quickly tweaked my example slightly and added a complete alternative example using the State monad below.</div>
<div>Both programs now have the same external behaviour.</div><div>It is a simpler example than the DFA that you are proposing. If I have time I'll look at your specific version of </div><div>the problem, but I am assuming that your main aim here is to understand the State monad better - rather than the DFA </div>
<div>exactly as you have specified it - so perhaps the following simple examples may help a little:</div><div><br></div><div>---------------------------------------------------</div><div><div>--</div><div>-- "aha!" </div>
<div>--</div><div>-- An exciting game that requires the string "aha!" to</div><div>-- be entered in order to reach the exit, rewarded with a "*".</div><div>--</div><div>-- A simple state machine.</div>
<div>--</div><div>-- Version 1 - not using the State monad...</div><div>--</div><div><br></div><div>import System.IO</div><div><br></div><div>type MyState = Char</div><div><br></div><div>initstate, exitstate :: MyState</div>
<div>initstate = 'a'</div><div>exitstate = 'z'</div><div><br></div><div>main = do hSetBuffering stdin NoBuffering -- (just so it responds char by char on the terminal)</div><div> stateIO initstate</div>
<div> </div><div>stateIO :: MyState -> IO ()</div><div>stateIO s = do c_in <- getChar</div></div></div></blockquote></div></div><div> let (str_out, s') = stateMC' c_in s</div><div> putStr str_out -- (newline flushes the output)</div>
<blockquote type="cite"><div style="word-wrap:break-word"><div><div> stateIO s' </div><div><br></div></div></div></blockquote><div><div>-- now uses exactly the same stateMC func as in version 2 below...</div>
<div>-- ('Y' = Yes, 'N' = No, '*' = congratulations game over, blank responses after game over)</div><div class="im"><div><br></div><div>stateMC' :: Char -> MyState -> (String, MyState)</div>
<div>stateMC' 'a' 'a' = (" Y\n", 'b')</div><div>stateMC' 'h' 'b' = (" Y\n", 'c')</div><div>stateMC' 'a' 'c' = (" Y\n", 'd')</div>
<div>stateMC' '!' 'd' = (" *\n", 'z')</div><div>stateMC' _ 'z' = (" \n", 'z')</div><div>stateMC' _ _ = (" N\n", 'a')</div><div>
<br></div></div></div><br><blockquote type="cite"><div style="word-wrap:break-word"><div><div><br></div><div><br></div></div><div class="im"><div>------------------------------------------------------------</div><div><br>
</div><div><div>--</div><div>-- Version 2 - using the State monad...</div><div>-- This time it treats the input as one long lazy String of chars </div><div>-- rather than char-by-char reading as in version 1</div><div>-- </div>
<div><br></div><div>import System.IO</div><div>import Control.Monad.State</div><div><br></div><div>type MyState = Char</div><div><br></div><div>initstate, exitstate :: MyState</div><div>initstate = 'a'</div><div>exitstate = 'z'</div>
<div> </div><div>main = do hSetBuffering stdin NoBuffering </div><div> interact mystatemachine </div><div><br></div><div>mystatemachine :: String -> String</div><div>mystatemachine str = concat $ evalState ( mapM charfunc str ) initstate</div>
<div><br></div><div>charfunc :: Char -> State MyState String</div><div>charfunc c = state $ stateMC' c -- wrap the stateMC' func in the state monad</div></div></div></div></blockquote><div><br></div><div><snip - remove previous comment></div>
<br><blockquote type="cite"><div class="im"><div style="word-wrap:break-word"><div><div>stateMC' :: Char -> MyState -> (String, MyState)</div><div>stateMC' 'a' 'a' = (" Y\n", 'b')</div>
<div>stateMC' 'h' 'b' = (" Y\n", 'c')</div><div>stateMC' 'a' 'c' = (" Y\n", 'd')</div><div>stateMC' '!' 'd' = (" *\n", 'z')</div>
<div>stateMC' _ 'z' = (" \n", 'z')</div><div>stateMC' _ _ = (" N\n", 'a')</div><div><br></div></div><div>-------------------------------------------------------------</div>
<div><br></div><div>Advantages of using the State monad are not really obvious in this example, but perhaps it will help in clarifying</div><div>what it is doing. It is just wrapping the stateMC' function in a monadic wrapper so that you can make convenient use of the</div>
<div>monadic operations >>= etc. and associated functions like mapM etc. for sequencing state computations.</div><div>'evalState' takes the chained sequence of state computations, produced by mapM in this case, feeds the initial value into the</div>
<div>beginning of the chain, takes the output from the end (which is a pair ([String], MyState) in this case) throws away the final MyState as we are</div><div>not interested in it here and keeps the [String] (which is then flattened to a single string with concat). </div>
<div>+Thanks to the wonders of laziness it works on it char by char as we go along :-)</div><div><br></div><div>In less trivial cases it helps keep the clutter of the common state handling away from the specifics of what you </div>
<div>are doing, like in the Real World Haskell parser example where it nicely handles the parse state. </div><div>But I guess you are not asking about advantages/disadvantages, but how the hell it works ;-)</div><div>I have found it confusing too...</div>
<div>/Henry</div><div><br></div><div><br></div></div></div>_______________________________________________<br>Beginners mailing list<br><a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
</blockquote></div><br></div></blockquote></div><br>