How do you remove repeating events in reactive-banana
Asked Answered
X

2

6

In reactive-banana I've got an event stream that produces a series of numbers, some of which repeat several times in a row (I'm not concerned with all duplicates, just sequential duplicates). How can I modify that event stream to contain only non-sequential duplicates?

I tried using changes to convert it to a behavior thinking the behavior would only "change" when the event was a new number but instead the behavior triggers a change event every time a new input event is received.

Xylotomy answered 3/4, 2012 at 15:20 Comment(0)
S
5

Note that the changes function should only be used for binding to GUI toolkits and thelike, it should not be used for regular programming with events and behaviors.

A function that supresses duplicate event occurrences can be expressed in terms of the mapAccum and filterJust combinators as follows

skipEqual :: Eq a => Event t a -> Event t a
skipEqual = filterJust . fst . mapAccum Nothing . fmap f
    where
    f y (Just x) = if x == y then (Nothing,Just x) else (Just y,Just y)
    f y Nothing  = (Just y, Just y)

test = interpretModel skipEqual $ map (:[]) [1 :: Int,1,2,3,3,2]

Running test gives

*Main> test
[[1],[],[2],[3],[],[2]]

as desired.

In other words, you can simply imagine Event as a list of occurrences and then apply your beloved "list" combinators to that.

Scofield answered 3/4, 2012 at 16:58 Comment(3)
Oh, why didn't I think of that?! I've removed the ugly implementation from my answer in favour of this one.Thrown
if you shouldn't use changes, how do you do anything meaningful with a behavior?Xylotomy
@Orclev: You can apply behaviors to events. The <@> and <@ operators are used for that. Also, you can use mutual recursion between behaviors and events.Scofield
T
0

Well, changes doesn't turn anything into a Behavior; it just lets you observe the changes of a Behavior in NetworkDescription, so that you can glue it to external frameworks. The behaviour of changes is described as changes (stepper x e)return (calm e), so round-tripping an event through stepper and changes will have no effect other than calm (which simply discards all simultaneous occurrences but the first).

It's useful to have a combinator to discard occurrences that don't change the value, and I think some other FRP frameworks have one built in. But you can write your own pretty easily, as Heinrich's answer shows.

Thrown answered 3/4, 2012 at 15:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.