[Haskell-cafe] Is this a correct explanation of FRP?

Heinrich Apfelmus apfelmus at quantentunnel.de
Fri Mar 30 14:28:30 CEST 2012

Peter Minten wrote:
> I've been trying to get my head around Functional Reactive Programming
> by writing a basic explanation of it, following the logic that
> explaining something is the best way to understand it.
> Am I on the right track with this explanation?

I think so. Your explanation looks fine to me, except for one really 
subtle but really important issue:

> Stepped sounds a lot like stepper and we can create that function by
> making a few small adjustments.
>     type Time = Int
>     stepper :: a -> [(Time, a)] -> (Time -> a)
>     stepper d es = \t -> case takeWhile (\(t', _) -> t' <= t) es of
>                             [] -> d
>                             xs -> snd (last xs)

The correct definition of  stepper  uses  <  instead of  <=

     ... case takeWhile (\(t', _) -> t' < t) es of ...

In other words, at the moment  t == t' , the behavior still returns the 
"old" value, not the "new" value from the event. This important because 
it allows for recursive definitions, like

     let b = accumB 1 e
         e = (+) <$> b <@ eKey

If you were to use  <=  here, then the new value of the behavior would 
depend on itself and the result would be undefined.

(Actually, even if you use the correct definition for  stepper,  trying 
to implement Event and Behavior in terms of  [(Time,a)]  and  Time -> a 
  in Haskell would give undefined on this recursive example. That's 
because the data types still aren't lazy enough, you have to use another 
model. That's one reason why implementing FRP has traditionally been hard.)

> P.S. Sorry about the long mail, the explanation ended up a little longer
> than I originally expected. :)

I know it was time to get a blog when my mailing list posts got too long. ;)

Best regards,
Heinrich Apfelmus


More information about the Haskell-Cafe mailing list