stonegrizzly
stonegrizzly

Reputation: 229

Recursion with the IO and State monads

I'm trying to implement a game in Haskell. I have a GameState type that manages things like the score, the players, and the rounds, where rounds are a RoundState type that manages the details of the game. To play the game, I have a function

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

where

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

This isn't very interesting though, because I can't output anything to the screen without the IO monad.

How can I wrap this function in the IO monad while keeping the recursion on playGame?

Upvotes: 3

Views: 279

Answers (1)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

Currently your monad is just state, no IO:

State (GameState g)

What you want is a monad with state and IO:

type Game g = StateT (GameState g) IO

And now you can use the monad as you might expect

import Control.Monad.IO.Class (liftIO)

-- ...

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

Upvotes: 7

Related Questions