Jeff, this is really great, slightly mind-bending stuff. It might be worth making a third-party library of fancy signal combinators (debounce, throttle). That said, I feel that filterMap has
come up enough times that it should be added to the standard lib. Here's another implementation, from the link:
justs : a -> Signal (Maybe a) -> Signal a
justs a sma = lift (maybe a identity) (keepIf isJust Nothing sma)
Notice that this version does not include the implicit lift.
<thread hijack> I was trying to solve a similar problem the other day: tooltips. Forget collision detection for a moment, just say we have a Signal Bool and we want to to create the tooltip half a second after a True, but remove it as soon as we see a False. Additionally, if the signal goes False before that half-second, the tooltip should be cancelled. After some thought, I realized the correct abstraction is
delayBy : (a -> Time) -> Signal a -> Signal a
I'm not sure how to implement this because of canceling scheduled events. delayBy preserves the ordering of events (except for dropping): when event2 fires (after its delay), event1 is cancelled if it has not already fired. But it would make tooltips easy: delayBy (\b -> if b then 0.5*second else 0) sigBool