Skip to content

Missing event when combining <@>, filterE, fmap, union, and collect #79

Description

@gelisam

The following looks complicated, so let me begin by proving that this is a real bug: this is a situation where adding a call to fmap id changes the number of events produced by the program!

The reason it is complicated is because it need to be: many different pieces are needed in order to trigger the issue. If I remove the fmap id, or the useless looking filterE (const True), or the seemingly unrelated "filtered event" part of the output, the bug disappears.

All right, so here's the code.

{-# LANGUAGE ScopedTypeVariables #-}
module Main where

import Reactive.Banana
import Reactive.Banana.Frameworks


network :: forall t. Event t () -> Event t String
network inputEvent = outputEvent
  where
    appliedEvent :: Event t Int
    appliedEvent = (\_ _ -> 0) <$> lastValue <@> inputEvent

    filteredEvent :: Event t Int
    filteredEvent = filterE (const True) appliedEvent

    fmappedEvent :: Event t Int
    fmappedEvent = fmap id (filteredEvent)

    outputEvent :: Event t String
    outputEvent = (const "filtered event" <$> filteredEvent)
          `union` (show <$> collect (appliedEvent `union` fmappedEvent))

    lastValue :: Behavior t Int
    lastValue = stepper 1 $ fmappedEvent

main :: IO ()
main = do
    (addHandler, fire) <- newAddHandler
    register (interpretAsHandler network addHandler) putStrLn
    fire ()

So as the single inputEvent is fired, an appliedEvent with value 0 occurs in response, as does a filteredEvent and a fmappedEvent, all with the same value. Since all those events are simultaneous and I combine them with union, I expect outputEvent to occur multiple times, once for each side of the union. And indeed, it occurs twice: once with "filtered event", and once with "[0]". But here's the weird thing: if you remove the fmap id, or change almost anything else in the code, the second outputEvent becomes "[0,0]" instead. Which means it's probably the correct value.

If you replace the fmap id with fmap (const 1), the result is still [0], which means that it's the fmappedEvent is lost.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions