[Haskell-cafe] State Machine and the Abstractions

Ryan Ingram ryani.spam at gmail.com
Sun May 29 23:56:17 CEST 2011


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 <limestrael at 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110529/7091138b/attachment.htm>


More information about the Haskell-Cafe mailing list