# Loop with the StateT monad

9 messages
Open this post in threaded view
|

## Loop with the StateT monad

 This is an exercise to learn the StateT monad. The program implements the game Morra. The two players are the computer and a person. The state accumulates the score of the computer and player. The program works for one iteration of function morra only. However I am at a loss how to loop it. I have tried a few things but nothing seems to work. I have narrowed the problem down to the "p <- liftIO getChar" statement. The second time through the loop it isn't executed. I have bracketed the statement with "liftIO \$ putStrLn "before" and liftIO \$ putStrLn "after". This is the program: module Morra where import Control.Monad.Trans.State.Lazy import Control.Monad.IO.Class import Data.Char (isDigit, digitToInt) import System.Random (randomRIO) import Control.Monad (when) morra :: StateT (Int, Int) IO () morra = do    liftIO \$ putStrLn "before"    p <- liftIO getChar    liftIO \$ putStrLn "after"    when (isDigit p) \$ do      let p' = digitToInt p      c <- liftIO \$ randomRIO (1, 2)      liftIO \$ putStrLn ("P: " ++ [p])      liftIO \$ putStrLn ("C: " ++ show c)      (pt, ct) <- get      if even (c + p') then do        liftIO \$ putStrLn "Computer Wins"        put (pt, ct + 1)      else do        liftIO \$ putStrLn "Player Wins"        put (pt + 1, ct)      morra main :: IO () main = do    putStrLn "-- p is Player"    putStrLn "-- c is Computer"    putStrLn "-- Player is odds, Computer is evens."    (personS,compS) <- execStateT morra (0,0)    putStrLn ("Person Score: " ++ show personS)    putStrLn ("Computer Score: " ++ show compS)    if personS > compS then      putStrLn "Winner is Person"    else      putStrLn "Winner is Computer" and this is the output: *Morra> main -- p is Player -- c is Computer -- Player is odds, Computer is evens. before 1 after P: 1 C: 2 Player Wins before after Person Score: 1 Computer Score: 0 Winner is Person *Morra> _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafeOnly members subscribed via the mailman list are allowed to post.
Open this post in threaded view
|

## Re: Loop with the StateT monad

 On Sat, Mar 18, 2017 at 1:52 AM, wrote: I have narrowed the problem down to the "p <- liftIO getChar" statement.It does run the second time, and gets the newline following the entered character. You should probably use getLine, or learn how your platform switches between default line-oriented input and character-oriented --- and how to switch it back afterward. (In C on Unix-like systems, this involves termios.)-- brandon s allbery kf8nh                               sine nomine associatesunix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafeOnly members subscribed via the mailman list are allowed to post.
Open this post in threaded view
|

## Re: Loop with the StateT monad

 Am 18.03.2017 um 07:45 schrieb Brandon Allbery: > On Sat, Mar 18, 2017 at 1:52 AM, <[hidden email]> wrote: > >> I have narrowed >> the problem down to the "p <- liftIO getChar" statement. >> > > It does run the second time, and gets the newline following the entered > character. You should probably use getLine, or learn how your platform > switches between default line-oriented input and character-oriented --- and > how to switch it back afterward. (In C on Unix-like systems, this involves > termios.) System.IO.hSetBuffering is your friend ben@yuiitsu1:~> ghci Prelude> import System.IO Prelude System.IO> :info hSetBuffering hSetBuffering :: Handle -> BufferMode -> IO () Prelude System.IO> :info BufferMode data BufferMode   = NoBuffering | LineBuffering | BlockBuffering (Maybe Int) Prelude System.IO> hSetBuffering stdin NoBuffering Prelude System.IO> getChar >> getChar Prelude System.IO> getChar >> getChar xy'y' # prompt returns immediately after i hit 'y' Prelude System.IO> _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafeOnly members subscribed via the mailman list are allowed to post.
Open this post in threaded view
|

## Re: Loop with the StateT monad

 On Sat, Mar 18, 2017 at 6:27 PM, Ben Franksen wrote:System.IO.hSetBuffering is your friendExcept when it's your enemy: https://github.com/commercialhaskell/stack/issues/2884 see also http://tunes.org/~nef/logs/haskell/17.03.18 at 02:48:19 and following.This conflation is stupid, prone to cause problems when multiple processes are involved, and needs to go away. Trying to hide the difference between buffering and tty mode from users just causes problems, because buffering is process local but the tty mode is shared between all processes using the tty.-- brandon s allbery kf8nh                               sine nomine associatesunix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafeOnly members subscribed via the mailman list are allowed to post.
Open this post in threaded view
|

## Re: Loop with the StateT monad

 Am 18.03.2017 um 23:34 schrieb Brandon Allbery: > On Sat, Mar 18, 2017 at 6:27 PM, Ben Franksen <[hidden email]> > wrote: > >> System.IO.hSetBuffering is your friend > > > Except when it's your enemy: > https://github.com/commercialhaskell/stack/issues/2884 see also > http://tunes.org/~nef/logs/haskell/17.03.18 at 02:48:19 and following. > > This conflation is stupid, prone to cause problems when multiple processes > are involved, and needs to go away. Trying to hide the difference between > buffering and tty mode from users just causes problems, because buffering > is process local but the tty mode is shared between all processes using the > tty. I don't understand. """ geekosaur commented on 30 Dec 2016 some ghc versions back, ghc's Unix runtime started conflating NoBuffering with stty -icanon """ What exactly is meant here with "conflate"? When you turn off buffering for stdin, then of course backspace cannot work. That should be clear. Cheers Ben _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafeOnly members subscribed via the mailman list are allowed to post.
Open this post in threaded view
|

## Re: Loop with the StateT monad

Open this post in threaded view
|