[Haskell-beginners] Reactive Banana Data Structures Sanity Check
Heinrich Apfelmus
apfelmus at quantentunnel.de
Fri Sep 14 15:45:49 CEST 2012
Michael Litchard wrote:
> I'm making an implementation of Grand Theft Wumpus using
> reactive-banana. I'm using the slot machine example to work from.
>
> For now, I'm just building a simple graph where a Player can move from
> Node to Node. I'm not sure I have the Data Structures right, so I
> wanted to run it by the community. I'm conceptualizing each Node (a
> Street) and the Player as a Behavior. I reason that since the Graph
> won't change, just the values inside a Node, I can update any Node as
> needed, instead of creating a new Graph whenever a value in a Node
> changes. It seems though, as I scale up, I'd end up with a big union
> of Behaviors. Does it make sense to describe each Node as a Behavior?
> Even though I'm starting simply, I intend to write a complete
> implementiation.
>
> http://nostarch.com/download/Lisp08.pdf
>
> data StreetName = [...]
>
> type Player t = Behavior t Player_
> type Street t = Behavior t Street_
>
> data Player_ = Player {location :: StreetName } deriving Show
> data Street_ = Street_ {sName :: StreetName
> ,player :: Maybe Player_
> } deriving Show
>
> data GameEvent = MovePlayer Street
> | Look
>
> does that look okay so far?
That's hard to say. It certainly doesn't look wrong, but whether it's a
good idea or not depends on what you will do later.
My process for programming with Functional Reactive Programming (FRP) is
usually this:
* What is the "end product", i.e. the thing that users ultimately
interact with? In your case, it's probably the drawing of a map of the city.
* Does the end product "vary in time"? Yes? Then it's going to be a
Behavior City , i.e. a data structure that describes the evolution of
the city in time.
* How does the city evolve in time? Here I start to think of the events
and other behaviors that I use to define the behavior, for instance by
writing
bcity :: Behavior City
bcity = stepper ... -- step function from events
or
bcity = (++) <$> bsuburbs <*> bcenter -- combine other behaviors
and so on.
The process is a bit like thinking as a physicist in god-mode: for each
object in my little universe, I specify where it should be at any
particular time, like 5 o'clock.
That said, I found it useful to decouple the interaction of individual
parts -- city, node, player -- from their time evolution. Have a look at
the Asteroids.hs example
http://www.haskell.org/haskellwiki/Reactive-banana/Examples#asteroids
The bottom part of the source contains function like advanceRocks or
collide that specify more complicated interactions between different
objects. The FRP part of the source file just specifies *when* these
interactions take place, i.e. advanceRocks happens when etick
happens while the player moves when eleft or eright happen.
In other words, my rule of thumb is
How does it happen? => ordinary functions
When does it happen? => events and behaviors
In particular, you can write your Wumpus game logic by asking the "how"
questions first and only then ask the "when" questions. Thus, I would
rename Player_ to Player for the "how" part and simply use Behavior
t Player for the fairly small "when" part.
Hope that helps.
Best regards,
Heinrich Apfelmus
--
http://apfelmus.nfshost.com
More information about the Beginners
mailing list