Closed dederer closed 6 years ago
I don't think this is actually an issue with withAccumArray
. The issue is that subscriptions are really a view artifact, but we are calculating them on each app input rather than lazily, like we do with the view proper.
In your example, you have the initial subscriptions, and two initial effects. So it goes:
Note that this results in the subscriptions being calculated 3 times during the course of the initial run
of the event queue before the commit, which is why you get duplicates. I think the answer is probably to just calculate subscriptions whenever we render, not on each input.
I see. In your sub-example no effects and therefore no problem with duplicate subscriptions.
To avoid duplication in my example, I can use the special InitialSub
as a marker:
data Sub a
= InitialSub
| Sub String
Put it first in the subs
:
, subs: const $ App.batch
[ InitialSub
, Sub "sub 1"
, Sub "sub 2"
]
And use it to remove duplicates:
subInterpreter :: forall i eff. Interpreter (Eff (console :: CONSOLE | eff)) Sub i
subInterpreter = Interpreter $ EventQueue.withAccum \queue -> pure
{ init: []
, update: \buffer i -> pure $ case i of
InitialSub -> []
_ -> A.snoc buffer i
, commit: \buffer -> do
log $ show $ buffer <#> case _ of
InitialSub -> ""
Sub t -> t
pure []
}
How do you think, is there another, more correct solution?
The correct solution is to fix how the library queues subscriptions :P. This current behavior is clearly lacking. I might go ahead and change the event queue stuff to always take an Array
as input, which avoids the need to have things like withAccumArray
anyway.
Thanks!
The resulting array
Array (Sub i)
, which is passed to thecommit
function, contains duplicate elements. It looks like a bug.Here is the code that demonstrates it (full code at: https://github.com/dederer/spork-accum-problem).
Expected output to console:
Instead, as a result: