
Judah Jacobson wrote:
I think you're saying that you want to write "w <- newIOWitness" at the top level, so that w can then be referenced in a pure function. Fair enough. But newIOWitness's implementation requires writeIORef (or an equivalent), which is not ACIO, right?
newIOWitness is very like newUnique. In both cases, the internal implementation updates an MVar to make them unique. Internally the open-witness package would use unsafeIOtoACIO (just as it already uses unsafeCoerce), but an exposed newIOWitnessACIO would be safe.
oneshot uniqueVar :: IO (TVar Integer) uniqueVar =< atomically $ newTVar 0 -- alternately, use newTVarIO
uniqueIntSTM :: IO (STM Integer) uniqueIntSTM = uniqueVar >>= \v -> return $ do n <- readTVar v writeTVar v (n+1) return n
getUniqueInt :: IO Integer getUniqueInt = uniqueIntSTM >>= atomically
This complicates the purpose of STM, which is to make composable STM transactions. I would rather do this: uniqueVar :: TVar Integer uniqueVar <- newTVarACIO uniqueInt :: STM Integer uniqueInt = do n <- readTVar uniqueVar writeTVar uniqueVar (n+1) return n AFAICT, one-shots are less powerful and just as complicated as an ACIO monad. -- Ashley Yakeley