
On Apr 27, 2008, at 9:36 AM, Conal Elliott wrote:
First, I think we want readTMVar instead of takeTMVar in newTIVal.
I don't see any reason it would hurt to use takeTMVar, and I suspect the garbage collector might be slightly happier this way since it potentially means once less reference to the data stored in the TMVar.
I think we *do* want unsafeNewEmptyTMVar inlined. Here's a convenient caching wrapper:
cached :: STM a -> TIVal a cached m = TIVal m (unsafePerformIO newEmptyTMVarIO)
The instances are then lovely:
instance Functor TIVal where f `fmap` tiv = cached (f `fmap` force tiv)
instance Applicative TIVal where pure x = cached (pure x) ivf <*> ivx = cached (force ivf <*> force ivx)
instance Monad TIVal where return x = cached (return x) tiv >>= k = cached (force tiv >>= force . k)
Yes, this is essentially what I am working with in Reaction at the moment. It seems to be working great, but I have not specifically tested the caching behavior yet, only that it doesn't screw up what I had working in the first place. I must admit that I think I don't fully understand the implications of inlining vs. not inlining unsafePerformIO. - Jake