如何在这里正确使用 StateT monad?
How to properly use the StateT monad here?
我必须在 Haskell 中为我学习的课程制作一个非常小的游戏。所以我创建了播放功能,但现在我无法更改它的类型签名。
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 的类型签名应该是:
play :: IO (Either ParseError [[String]]) -> StateT GameState IO Score
但是我完全不知道如何使用我的 StateT
monad?我怎样才能做到这一点? IO (Either ParseError [[String]])
monad 是来自缺失的 H 包的 parseFromFile 函数的结果。
来电者应该处理那个。
main :: IO ()
main = do
parsed <- parseFromFileStuff
case parsed of
Left parseerror -> handleErrorStuff
Right input -> evalStateT (play input) initialState
顺便说一下,你从来没有真正 return 得分,所以 play
的 return 类型应该是 Void
,而不是 Score
。此外,您应该通过删除 play
的最后一行、将其 return 类型更改为 ()
并将 play input
替换为 forever (play input)
来收紧该递归。哦,你从不使用输入。
我必须在 Haskell 中为我学习的课程制作一个非常小的游戏。所以我创建了播放功能,但现在我无法更改它的类型签名。
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 的类型签名应该是:
play :: IO (Either ParseError [[String]]) -> StateT GameState IO Score
但是我完全不知道如何使用我的 StateT
monad?我怎样才能做到这一点? IO (Either ParseError [[String]])
monad 是来自缺失的 H 包的 parseFromFile 函数的结果。
来电者应该处理那个。
main :: IO ()
main = do
parsed <- parseFromFileStuff
case parsed of
Left parseerror -> handleErrorStuff
Right input -> evalStateT (play input) initialState
顺便说一下,你从来没有真正 return 得分,所以 play
的 return 类型应该是 Void
,而不是 Score
。此外,您应该通过删除 play
的最后一行、将其 return 类型更改为 ()
并将 play input
替换为 forever (play input)
来收紧该递归。哦,你从不使用输入。