[Haskell-cafe] Stronger STM primitives needed? Or am I just doing it wrong?

Matthew Brecknell haskell at brecknell.org
Tue Apr 22 18:47:31 EDT 2008

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.

More information about the Haskell-Cafe mailing list