2013-11-02 47 views
3

我想在Haskell中实现一个游戏。我有一个GameState类型,用于管理比分,玩家和回合等事物,其中回合是一个RoundState类型,用于管理游戏的详细信息。为了玩游戏,我有一个函数递归与IO和状态单元

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单子。

如何在IO单元中包装这个函数,同时保持playGame的递归?

+0

您可以添加您的导入,以及'Player'和'GameState'类型,以便其他人可以首先所有编译你的代码,请? –

+0

你需要'Monad Transformers',特别是'StateT',检查你可以找到一个例子[here](http://www.haskell.org/haskellwiki/Simple_StateT_use) – chamini2

回答

7

目前你的单子只是状态,没有IO

State (GameState g) 

你想要的是与国家和IO单子:

type Game g = StateT (GameState g) IO 

现在你可以使用单子正如您所料

import Control.Monad.IO.Class (liftIO) 

-- ... 

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