Behavior that is both recursive, and depends on other behaviors
Asked Answered
S

1

6

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?
Sitar answered 11/8, 2014 at 22:43 Comment(3)
Looks like you just need apply, a.k.a. (<@>)Lyda
A very FRP way to do physics involves integral :: (VectorSpace v) => Behavior v -> Behavior v, which reactive-banana does not provide, but which can be approximated (in essentially the way you describe here, but the meaning is the important thing!).Lyda
@Lyda Could you elaborate on apply? I mean, I don't have any event relevant for its argument. If reactive-banana isn't 100% perfectly suited for the task could you please suggest an FRP library that would be more complete for me (and hopefully one with integral you mentioned)?Sitar
R
5
  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
    
Richburg answered 12/8, 2014 at 9:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.