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

Bertram Felgenhauer bertram.felgenhauer at googlemail.com
Wed Apr 14 12:36:00 EDT 2010

Limestraël wrote:
> Okay, I just understood that 'Prompt' was just a sort of view for 'Program'.


> >   runMyStackT :: MyStackT (Player m) a -> Player m a
> According to what Bertram said, "each strategy can pile its own custom monad
> stack ON the (Player m) monad".

Yes, and I meant what Heinrich wrote, you wrap some transformer around
the common Player m monad.

> > game :: Monad m => Player m () -> Player m () -> m ()
> As it is written, it requires both players to run in the SAME monad.
> And if have a network player ( e.g.* Player (StateT Handle IO)* ) and an AI
> storing former opponent's moves ( e.g. *(Monad m) => Player (StateT [Move]
> m)* ), then they can't be in the same monad...

The idea is to pick m = IO, and then use

  type NetPlayer a = StateT Handle (Player IO) a


  type AIPlayer a = StateT [Move] (Player IO) a

or possibly

  type AIPlayer a = StateT [Move] (Player Identity) a

using the mapPlayerM (or mapMonad as suggested by Heinrich) function.

You'd then provide functions like

    runAIPlayer :: AIPlayer a -> Player IO a
    runAIPlayer player = {- mapMonad (return . runIdentity) $ -}
        evalStateT player []

This gives you most of what you want: You can add custom state and the
like to each player. You can not hope to exchange the base monad m,
because then the 'game' function would have to know how to run both
of those base monads simultaneously. A function like mapMonad is the
best device you can hope for, I think.



More information about the Haskell-Cafe mailing list