1

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.

3
  • 1
    I don't see why you need to alter play. Whatever calls parseFromFile should be deciding, based on that result, whether or not to call play. Commented Apr 12, 2016 at 18:20
  • @chepner Ok, but how can I call play with the [[String]] instead of the IO (Either ParseError [[String]])? I don't have access to the [[String]] rightaway. Commented Apr 12, 2016 at 18:23
  • 2
    You can use lift :: IO (Either ParseError [[String]]) -> StateT GameState IO (Either ...) and then use monadic bind (>>= or inside a do block) on this value. You will still need to deal with the ParseError - perhaps throwing an exception or changing your monad to StateT GameState (ErrorT SomeErrorType IO) Commented Apr 12, 2016 at 18:54

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! This works as expected :) The input is used in another function that I didn't include in this implementation of play ;)