Hacker News new | past | comments | ask | show | jobs | submit login

Yes, I think your alternate names make more sense when you think about `Behavior`s only. That said, from what I understand of FRP you don't want to think of the data type as "type T is for Behaviors" or "type S is only for Events", because it's so easy to compose them. If I have even an `Event ()` (an event source with no data beyond the fact that it fired), I can use (<@) to view the `Behavior T`, and now I have an `Event T`.

If the function in OP was returning an Event, it would be a sequence of instructions to the freezer: "turn on now", "turn off now" and so on. As a Behavior, it's more like a set of times when the fridge should be on or off.




Ah I see. Events form a Monoid, so I guess I could have a "something happens" event aggregating all the sensor updates, and sample the "inverterPowerChange" Behaviour at the occurrences of the Event.

The API for reactive-banana doesn't seem to have a "value changed" combinator that creates an Event from a Behaviour alone; one must sample the Behaviour with another Event.

(Other FRP libraries somewhat similar in philosophy like reflex—not the JS Reflex—do seem to have Behaviour-like things that can fire events on change: http://hackage.haskell.org/package/reflex-0.4.0.1/docs/Refle... Although reactive-banana seems simpler to understand.)


reactive-banana does have a function from Behavior a -> Event (Future a) but that Future gets in the way and removing it is only for wizards.

On the other hand, I think that's necessary for mutually recursive definitions of behaviors and events to reach a fixed point, which is quite a neat feature although not one I've needed yet.


A piece of folk wisdom I picked up along the way was you often end up needing a "Behavior a" and an "Event a" that fires when the Behavior changes. The reason I switched from dabbling-with-reactive-banana to dabbling-with-reflex is exactly that I needed "Dynamic"s.The semantics for Behavior require that it doesn't appear to change value until the frame has finished updating, so you either need to keep an Event around that fires the "new value" in the current frame or use a more powerful library.

Remark: Event is a Monoid or a Semigroup only when the contained value is either a Semigroup. The most useful combining ability comes from Behavior's Applicative instance.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: