It looks like joining events in this manner isn t going to work. Try this instead:
import FRP.Reactive
import FRP.Reactive.FieldTrip
import Graphics.FieldTrip
import Control.Monad
import Control.Applicative
flipflop = stepper "none" $ either (const "flip") (const "flop")
<$> eitherE (atTimes ((+2) <$> [0,5..])) (atTimes [5,10..])
txtGeom = ((uscale2 (0.5::Float) *%) . utext . show <$>)
main = anim2 (txtGeom . pure flipflop)
Unfortunately there s still a space leak in this version, but it s much smaller. After running for about a minute the total RAM usage was about 9.7MB.
There s also a flipFlop
function that creates a Behavior Bool
. This worked well for the flip-flop, but I didn t see a clean way to add "none" for the first two seconds.
I also tried this
flipflop = stepper "none" $ (const "flip" <$> (atTimes ((+2) <$> [0,5..])))
`mplus` (const "flop" <$> atTimes [5,10..])
which appears to work identically to the first version.
Of course, this doesn t do much for dynamically scheduling in the manner your asking about. Unfortunately I don t believe this use-case works in Reactive.
I very much admire the work that s produced Reactive, and I want to like it, but it seems to be extremely tricky to reason about. This thread from the mailing list is an example of the sort of problem (and solution!) that seems to be common. Also the "unamb" library (which underlies much of Reactive) exposed a number of very subtle bugs in GHC s threading that played havoc with results until they were fixed around ghc-6.12. Although that is not in any way the fault of Conal or other Reactive contributors, it made it that much harder to use the framework, particularly with earlier GHC s.
You might try some of the other FRP packages. Yampa has a sound implementation, and I ve heard that Elerea is relatively simple to pick up, and it has a nice demo application.