Yves Parès wrote:
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 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.

There are several methods to specify state machines, sequential composition of actions is just one of them. Let me elaborate.

First and foremost, you can express every state machine as an automaton. For instance, your example above could be written as

   state1  -->  (MoveTo point1, state2)
   state2  -->  (MoveTo point2, state3)
   state3  -->  ((), state1)

An automaton is a set of states and transitions between them, and you should imagine that all your state machines work like this.

Of course, while all state machines *work* like this, this does not mean that you have to *specify* them like this. For instance, writing down the states for a long sequence of actions like

   do
     moveTo point1
     moveTo point2
     shoot
     moveTo point3
     ...etc.

would be very cumbersome, you'd have to invent one dummy state for each action in the sequence. And this is where do-notation comes in: it's a way to specify long sequences of actions and have the interpreter automatically generate the intermediate dummy states!

As you note, however, not all state machines are sequences of actions, far from it, actually. Sometimes, you want to write

    Flee   --> MoveTo point0
    Attack --> shoot `during` MoveTo point1

Well, nobody forces you to use do-notation in that case, right?

In other words, I propose that you invent a small set of *state machine combinators* that allow you to freely mix do-notation (or something less powerful) with state transitions. Parallel composition corresponds to pairing states.


(Chances are that you can express everything with do-notation by introducing threads and combinators like during or fork , but I don't know whether that's the best way to go about it. It's worth trying, but keep in mind that the goal is to have an expressive set of combinators, not to shoehorn everything into monads.)



Best regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to