Search code examples
haskellmonadsmonad-transformersstate-monad

How to properly use the StateT monad here?


I'm have to make a very small game in Haskell for a course I follow. So I created the play-function, but now I have trouble changing it's type signature.

play :: [[String]] -> StateT GameState IO Score
play input = 
do 
    liftIO $ clearScreen
    (answered, correct) <- get
    if True
    then
        do
            liftIO $ putStrLn "Well done! Your answer was correct!"
            liftIO $ putStrLn ("So far, you answered " ++ (show answered) ++ " questions")
            put (answered + 1, correct + 1)
            liftIO $
                do
                    temp <- getLine
                    putStrLn temp
    else
        do
            liftIO $ putStrLn "I'm sorry, you're wrong..."
            put (answered + 1, correct)
    play input

Now, please don't mind the if True statement, that's just for testing. Now this function works, but I have to make it work with another type signature to. The type signature of the function play should be:

play :: IO (Either ParseError [[String]]) -> StateT GameState IO Score

But I have absolutely no idea on how to use my StateT monad then? How can I do this? The IO (Either ParseError [[String]]) monad is a result of the parseFromFile-function from the missingH-package.


Solution

  • The caller should be handling that.

    main :: IO ()
    main = do
      parsed <- parseFromFileStuff
      case parsed of
        Left parseerror -> handleErrorStuff
        Right input -> evalStateT (play input) initialState
    

    By the way, you never actually return a score, so the return type of play should be Void, not Score. Also you should tighten that recursion by removing plays last line, changing its return type to (), and replacing play input by forever (play input). Oh and you never use the input.