Frage

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.

War es hilfreich?

Lösung

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.

Andere Tipps

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top