Search code examples
haskellreactive-programmingfrpreactive-banana

How do you remove repeating events in reactive-banana


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.


Solution

  • 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.