[Haskell-cafe] Simple game: a monad for each player

Limestraël limestrael at gmail.com
Wed Apr 14 10:43:20 EDT 2010

Yves, that is exactly how I designed my program so far.
Human player needs a monad IO, AI needs just a monad, whatever it is, and I
make both run in IO.

And, as you said, the type of the ai (bot :: Monad m => Player m) contains
no IO, so I know that, even if I make it run in IO, it won't make any

My problem was, for example, if I want a player to run in its OWN monad.
Human uses IO, which is unique and shared by all the human players in the
But what if I want an AI that remember every former opponent's move, so that
it could adapt its reflexion all along the game?
Then this AI would have to run in its own State monad, for instance.

2010/4/13 Tillmann Rendel <rendel at informatik.uni-marburg.de>

> Yves Parès wrote:
>> data Player m = Player {
>>    plName :: String,  -- unique for each player
>>    plTurn :: GameGrid -> m Move  -- called whenever the player must play
>> }
>  What I try to avoid is having every player running in IO monad.
> One could define the following players.
>  human :: MonadIO m => Player m
>  human = ...
>  bot :: Monad m => Player m
>  bot = ...
> Note that these players are polymorphic in m, only assuming some minimal
> interface.
> Now you can run both players in a single monad which is good enough for
> both, because it supports the union of the interfaces assumed by the various
> players. In this case, this monad could be IO, since it supports both
> MonadIO and Monad.
>  changeBoard :: Board -> Move -> board
>  changeBoard = ...
>  play :: Player IO -> Player IO -> GameGrid -> IO GameResult
>  play p1 p2 board do
>    move <- plTurn p1 board
>    play p2 p1 (changeBoard board move)
> While this is probably not as expressive as what you want, it is reasonably
> simple, and it has the property that bot is not in the IO monad.
> I have first seen this pattern in monadic interpreters, where you could
> have types like the following.
>  eval :: (MonadReader Env m) => Expression -> m Value
>  exec :: (MonadReader Env m, MonadIO m) => Statement -> m ()
> These types reflect that the interpreted language permits side-effects
> only in statements, but not in expressions. This is similar to your
> situation: You want your types to reflect that your game permits
> side-effects only in human players, not in artifical intelligences.
>  Tillmann
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100414/a95a8bbb/attachment.html

More information about the Haskell-Cafe mailing list