Ryan Ingram said: > How can I implement the following operation efficiently in STM? Given > a TVar "now", > > waitFor t0 = do > t <- readTVar now > if (t < t0) then retry else return () > > This naive implementation has the problem that the transaction gets > restarted every time "now" gets updated, even if the new value is > still less than t0.
I'm not familiar with FRP, so this may be off the mark. Are you familiar with Control.Concurrent.STM.TVar.registerDelay? I realise your concept of time differs from that of registerDelay, but I suspect you'll need to use a similar approach. > One primitive that would be strong enough is this: > retryUntil :: TVar a -> (a -> Bool) -> STM () > > although it would still do some computation every time "now" changed. I don't think a primitive retryUntil would be able to do any better than the obvious implementation (which looks a lot like your waitFor). > The thought I originally had was to register the "waitFor" time with > some helper which kept track of the current time and fired off a > notice when it was ready. But the problem with that is that "retry" > undoes all the work of setting that up; the goal is still to block, > but I want a stronger blocking primitive. That's essentially what registerDelay does. The key is that registering a timer must occur in the IO monad, outside the transaction that waits for it. I vaguely recall that there is at least one hackage library which is somewhat more sophisticated than registerDelay, so you might also want to look there. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe