如何在这里正确使用StateT monad?

时间:2016-04-12 18:08:52

标签: haskell monads monad-transformers state-monad

我必须在Haskell做一个非常小的游戏,我要遵循的课程。所以我创建了play-function,但现在我无法更改它的类型签名。

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

现在,请不要介意if True语句,仅用于测试。现在这个功能有效,但我必须使用其他类型的签名。功能播放的类型签名应为:

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

但我完全不知道如何使用我的StateT monad呢?我怎样才能做到这一点? IO (Either ParseError [[String]]) monad是来自missingH-package的parseFromFile函数的结果。

1 个答案:

答案 0 :(得分:3)

来电者应该处理它。

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

顺便说一句,您实际上从未返回分数,因此play的返回类型应为Void,而不是Score。此外,您应该通过删除play的最后一行,将其返回类型更改为(),并将play input替换为forever (play input)来加强该递归。哦,你永远不会使用输入。