Search code examples
haskellrecursionreactive-programmingfrpreactive-banana

Behavior that is both recursive, and depends on other behaviors


My network looks like this:

ePhysics :: Event t ()
bPlayerForce :: Behavior t (Double,Double)
bPlayerPosition :: Behavior t (Double, Double)

ePhysics is fired repeatedly from a timer.
I'm having issues with defining bPlayerPosition. What I intend is that it will start at (0,0), and whenever ePhysics is fired, bPlayerPosition will be recalculated using bPlayerForce as a parameter.

The problem is that in-order to specify an initial value I need to use accumB/stepper but they only work with events, and I can't get the force value from bPlayerForce since only behaviors can get the value of other behaviors (with <*>).

The alternative would be just using <*> but with that I have no initial value, so it becomes a meaningless infinite recursion:

let bPlayerPosition = pure calcPosition <*> bPlayerForce <*> bPlayerPosition

I have 3 questions:

  1. Is there a way of getting a value out of a behavior without <*>? like, when reactimateing or mapping an event? the issue of not being able to has been screwing with me constantly since the very start.
  2. Would there be a more functional/frp way to do physics? (in general and the ones specific to the question)
  3. How can I solve the presented problem?

Solution

    1. The apply combinator, also called <@>, and its variant <@ provide a way to sample a Behavior whenever an event happens.
    2. Looks fine to me. The Animation.hs example does something similar. You have to approximate the integral by summing over discrete time steps, which are given by your ePhysics event.
    3. Something along the lines of

      let bPlayerPosition = stepper (0,0) $
              (calcPosition <*> bPlayerForce <*> bPlayerPosition) <@ ePhysics