[Haskell-cafe] broadcasting stateful computations
Olaf Klinke
olf at aatal-apotheke.de
Wed Sep 1 14:44:38 UTC 2021
Dear Café,
I have a sequence of state-modifying computations
action :: MonadUnliftIO m => StateT s m ()
where the state s should be visible to other threads. Thus I created a
TVar in which I keep track of this state s for other threads to read.
The type system tells me it can't be done, which suggests I am using
the wrong abstraction. The following type-checks but may be unsafe.
import Control.Concurrent.STM
import Control.Monad.IO.Unlift
updateStateTVar :: MonadUnliftIO m => TVar s -> StateT s m () -> m ()
updateStateTVar var action = withRunInIO (\inIO -> do
s0 <- atomically (readTVar var)
s1 <- inIO (execStateT action s0)
atomically (writeTVar var s1))
Yet the splitting into readTVar and writeTVar is dangerous if several
threads have read/write access to the same TVar. I was hoping to write
the above using modifyTVar. However, the action essentially gives me a
Kleisli map
s -> m s
which I somehow have to turn into an
m (s -> s)
but it is not possible in general. (The reverse works for any functor.)
What should I do?
* Switch to WriterT (Endo s) m?
This is not as powerful as StateT s m.
* Do everything in the STM monad? But this disallows arbitrary IO
because it would facilitate nested STM transactions.
The code above is safe, I believe, if only one thread has read/write
access and the others are read-only. Are there type-level abstractions
of this kind? (I suppose one could easily make them with some
newtypes.)
Thanks in advance for any thoughts on this.
Olaf
More information about the Haskell-Cafe
mailing list