I suggest you take a look at MonadPrompt and/or Operational (two competing packages, one of which I wrote).
And yes, you probably need some operation Concurrent :: [Mission ()] -> Mission () or Interrupt :: Mission () -> Mission Bool -> Mission () -> Mission () which runs its first argument until the second argument returns True, then switches. On Fri, May 27, 2011 at 12:06 PM, Yves Parès <limestr...@gmail.com> wrote: > Hello, > > For the purposes of a simple strategy game, I'd like to build an EDSL that > expresses missions. A mission could be represented as a state machine. > With basic bricks such as actions (MoveTo, ShootAt...) or tests > (EnemiesAround, LowHealth...), I could (ideally dynamically) build some > strategic behaviors for the units. > I will take the example of a patrol. Applied to a unit (or a group of > units), it dictates : go from point 1 to point 2 and then go back and > repeat. But when you detect an enemy near, leave the patrol path, destroy it > and then resume your patrol where you left it. > > So if I consider my mission as a monad: > data Mission = MoveTo Point | ShootAt Unit > > patrol = do > MoveTo point1 > MoveTo point2 > patrol > > So far so good, but there, the only advantage to use a monad instead of a > list of MoveTo's is the do-notation. > And I lack the expression of tests. Using a GADT it could be: > > data Mission a where > MoveTo :: Point -> Mission () > ShootAt :: Unit -> Mission Bool -- If we have destroyed it or not > EnemiesAround :: Mission [Unit] -- The enemies that are maybe in sight > LowHealth :: Mission Bool -- If I should retreat > ... > > -- (Monad Mission could be nicely expressed using Heinrich Apfelmus' * > operational* package) > > patrol = do > MoveTo point1 > MoveTo point2 > enemies <- EnemiesAround > mapM_ ShootAt enemies > patrol > > Aaaaaaaand... here comes the trouble: the actions are done *sequentially*. > My units will move and then look at enemies, they will not monitor their > environment while they move. > So I need a way to say: A is your action of patrolling. B is your action of > surveillance. Do both in parallel, but B is preponderant, as if it successes > (if enemies are there) it takes over A. So, it is as if I was running two > state machines in parallel. > Moreover, the last line (the recursive call to patrol) is wrong, as it will > restart the patrol from the beginning, and not from where it has been left. > But this could be corrected by addind a test like "which point is the > closest". > > So I thought about Arrows, as they can express sequential and parallel > actions, but I don't know if it would be a right way to model the > interruptions/recoveries. > What do you think about it? Do you know of similar situations and of the > way they've been solved? > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe