IO和状态monad的递归

时间:2013-11-02 22:21:49

标签: haskell io monads

我正在尝试在Haskell中实现一个游戏。我有一个GameState类型,可以管理得分,玩家和回合等内容,其中回合是RoundState类型,用于管理游戏的细节。为了玩游戏,我有一个功能

playGame :: (RandomGen g) => State (GameState g) (Player, Int)
playGame = do playRound
              winner <- checkForWinner
              case winner of 
                  Nothing -> playGame
                  Just x -> return x

其中

checkForWinner :: RandomGen g => State (GameState g) (Maybe (Player, Int))
playRound :: RandomGen (g) => State (GameState g) ()

但这并不是很有趣,因为如果没有IO monad,我就无法输出任何内容。

如何在IO monad中包装此函数,同时保持playGame的递归?

1 个答案:

答案 0 :(得分:7)

目前你的monad只是州,没有IO

State (GameState g)

你想要的是一个有状态和IO的monad:

type Game g = StateT (GameState g) IO

现在你可以像预期的那样使用monad

import Control.Monad.IO.Class (liftIO)

-- ...

playGame :: (RandomGen g) => Game g (Player, Int)
playGame = do
    liftIO $ putStrLn "Look, I have IO"
    winner <- checkForWinner
    ...