Okay, I start to understand better...
Just, Heinrich, how would implement the mapMonad function in terms of the operational package?
You just shown the signature.
Limestraėl wrote:Right.
> Okay, I just understood that 'Prompt' was just a sort of view for 'Program'.
Yes, and I meant what Heinrich wrote, you wrap some transformer around
> > 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".
the common Player m monad.
The idea is to pick m = IO, and then use
> > 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...
type NetPlayer a = StateT Handle (Player IO) a
and
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.
regards,
Bertram
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe