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.
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 idchanges 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 lookingfilterE (const True), or the seemingly unrelated "filtered event" part of the output, the bug disappears.All right, so here's the code.
So as the single
inputEventis fired, anappliedEventwith value 0 occurs in response, as does afilteredEventand afmappedEvent, all with the same value. Since all those events are simultaneous and I combine them withunion, I expectoutputEventto occur multiple times, once for each side of theunion. And indeed, it occurs twice: once with "filtered event", and once with "[0]". But here's the weird thing: if you remove thefmap id, or change almost anything else in the code, the secondoutputEventbecomes "[0,0]" instead. Which means it's probably the correct value.If you replace the
fmap idwithfmap (const 1), the result is still[0], which means that it's thefmappedEventis lost.