<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:"Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:"\@Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:#954F72;
text-decoration:underline;}
.MsoChpDefault
{mso-style-type:export-only;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style></head><body lang=EN-CA link=blue vlink="#954F72"><div class=WordSection1><p class=MsoNormal>I have a metro to catch but small interesting additions worth looking into:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Using `modify` and lenses, you get niceties like this to update the state:</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>modify $ scolor .~ color</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Don’t forget to use ReaderT over StateT if you only need some configuration to be passed implicitly and wont mutate.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Last note, `StateT s m a` relies fairly heavily on understanding the essence of monads. Your goal is to build a computation in which you’re given the ability to keep and mutate a state `s`. At the end of the day, something has to “run†that computation, which will carry out its effects `m`. produce a </p><p class=MsoNormal>result `a`, and possibly give you the final state `s` if needed as well. (See runStateT vs. execStateT vs. evalStateT).</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Cheers,</p><p class=MsoNormal>Alex.</p><p class=MsoNormal><o:p> </o:p></p><div style='mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal style='border:none;padding:0cm'><b>From: </b><a href="mailto:toad3k@gmail.com">David McBride</a><br><b>Sent: </b>April 7, 2017 8:34 AM<br><b>To: </b><a href="mailto:beginners@haskell.org">The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell</a><br><b>Subject: </b>Re: [Haskell-beginners] State monad to help pass around game settings</p></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>The basic outline for using StateT for settings is the following.</p><p class=MsoNormal>Hopefully this will give you an idea of how to get started.</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>import Control.Monad.State</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>data Color = White | Red deriving (Enum, Show)</p><p class=MsoNormal>data Shape = Square deriving (Enum, Show)</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>data Stuff = Stuff deriving Show</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>data Settings = Settings {</p><p class=MsoNormal> sColor :: Color,</p><p class=MsoNormal> sShape :: Shape</p><p class=MsoNormal>} deriving Show</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>data MyApp = MyApp {</p><p class=MsoNormal> settings :: Settings,</p><p class=MsoNormal> otherStuff :: Stuff</p><p class=MsoNormal>} deriving Show</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>main = do</p><p class=MsoNormal> (_, settings) <- runStateT proc (MyApp (Settings White Square) Stuff)</p><p class=MsoNormal> print settings</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>-- A reusable prompt function.</p><p class=MsoNormal>prompt :: String -> [a] -> (Char -> a) -> IO a</p><p class=MsoNormal>prompt question opts c2r = do</p><p class=MsoNormal> putStrLn question</p><p class=MsoNormal> mapM undefined opts</p><p class=MsoNormal> c <- getChar</p><p class=MsoNormal> let r = c2r c -- turn a Char into a Shape or a Color.</p><p class=MsoNormal> return r</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>proc :: StateT MyApp IO ()</p><p class=MsoNormal>proc = do</p><p class=MsoNormal> getColor</p><p class=MsoNormal> getShape</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>getColor :: StateT MyApp IO ()</p><p class=MsoNormal>getColor = do</p><p class=MsoNormal> color <- liftIO $ prompt "What color would you like?" [Red, White] undefined</p><p class=MsoNormal> MyApp settings otherstuff <- get</p><p class=MsoNormal> put $ (MyApp (settings { sColor = color })) otherstuff</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>getShape :: StateT MyApp IO ()</p><p class=MsoNormal>getShape = undefined</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>On Thu, Apr 6, 2017 at 9:26 PM, Dave Martin <davemartinnyc@aol.com> wrote:</p><p class=MsoNormal>> I'm trying to write a game with a "settings menu" where the user can adjust</p><p class=MsoNormal>> gameplay options. Right now I pass all the settings around as parameters.</p><p class=MsoNormal>> I'm trying to figure out how to use the State monad to simplify this task,</p><p class=MsoNormal>> but I can't figure out how to start. Or maybe my whole design approach is</p><p class=MsoNormal>> wrongheaded, and not in keeping with best practices. Haskell is my first</p><p class=MsoNormal>> language. This is the kind of thing I have now:</p><p class=MsoNormal>><o:p> </o:p></p><p class=MsoNormal>> mainM color shape =</p><p class=MsoNormal>>  putStrLn "\n\nMain Menu" >></p><p class=MsoNormal>>  (putStrLn . unlines) [</p><p class=MsoNormal>>    "(1) Set",</p><p class=MsoNormal>>    "(2) Display",</p><p class=MsoNormal>>    "(3) Quit"] >></p><p class=MsoNormal>>  putStr "? " >></p><p class=MsoNormal>>  getChar >>= \c -></p><p class=MsoNormal>>    case c of</p><p class=MsoNormal>>      '1' -> set color shape</p><p class=MsoNormal>>      '2' -> display color shape</p><p class=MsoNormal>>      '3' -> return ()</p><p class=MsoNormal>>      _ -> mainM color shape</p><p class=MsoNormal>><o:p> </o:p></p><p class=MsoNormal>> set color shape =</p><p class=MsoNormal>>  putStrLn "\n\nSettings" >></p><p class=MsoNormal>>  (putStrLn . unlines) [</p><p class=MsoNormal>>    "(1) Color",</p><p class=MsoNormal>>    "(2) Shape",</p><p class=MsoNormal>>    "(3) Main Menu"] >></p><p class=MsoNormal>>  putStr "? " >></p><p class=MsoNormal>>  getChar >>= \c -></p><p class=MsoNormal>>    case c of</p><p class=MsoNormal>>      '1' -> setColor color shape</p><p class=MsoNormal>>      '2' -> setShape color shape</p><p class=MsoNormal>>      '3' -> mainM color shape</p><p class=MsoNormal>>      _ -> set color shape</p><p class=MsoNormal>><o:p> </o:p></p><p class=MsoNormal>> setColor color shape =</p><p class=MsoNormal>>  putStr ("\n\nColor is " ++ color ++ ". New color? ") >></p><p class=MsoNormal>>  getLine >>= \cs -></p><p class=MsoNormal>>  set cs shape</p><p class=MsoNormal>><o:p> </o:p></p><p class=MsoNormal>> setShape color shape =</p><p class=MsoNormal>>  putStr ("\n\nShape is " ++ shape ++ ". New shape? ") >></p><p class=MsoNormal>>  getLine >>= \cs -></p><p class=MsoNormal>>  set color cs</p><p class=MsoNormal>><o:p> </o:p></p><p class=MsoNormal>> display color shape =</p><p class=MsoNormal>>  putStrLn ("\n\nColor is " ++ color ++ ". Shape is " ++ shape ++ ".") >></p><p class=MsoNormal>>  mainM color shape</p><p class=MsoNormal>><o:p> </o:p></p><p class=MsoNormal>><o:p> </o:p></p><p class=MsoNormal>> _______________________________________________</p><p class=MsoNormal>> Beginners mailing list</p><p class=MsoNormal>> Beginners@haskell.org</p><p class=MsoNormal>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</p><p class=MsoNormal>><o:p> </o:p></p><p class=MsoNormal>_______________________________________________</p><p class=MsoNormal>Beginners mailing list</p><p class=MsoNormal>Beginners@haskell.org</p><p class=MsoNormal>http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</p><p class=MsoNormal><o:p> </o:p></p></div></body></html>