[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