I'm writing a function, where I process a list using forM_
, and append the result to a TVar
list:
import Control.Concurrent.STM
import Control.Concurrent.STM.TVar
import Control.Concurrent (forkIO)
import Control.Monad (forM_)
insert :: a -> [a] -> [a]
insert = (:) -- stub
my_func_c :: (a -> a) -> [a] -> IO [a]
my_func_c my_function arr = do
res_var <- atomically $ newTVar ([]::[a])
forkIO $ forM_ arr $ \x -> atomically $ do
let y = id $! my_function x
modifyTVar res_var (insert y)
atomically $ readTVar res_var
The result is always empty, if I compile it with -threaded
. How is it possible to wait for the threads to finish? I can not use MVar
or Async
. I have to solve this problem using TVar
, or other data structures which are based on TVar
The idiomatic solution would be to use
TMVar
s:but if you are really only allowed to use
TVar
s, you can simulate aTMVar ()
with aTVar Bool
:Under the hood,
TMVar a
is just aTVar (Maybe a)
(soTMVar ()
~TVar (Maybe ())
~TVar Bool
) withtakeTMVar
doing areadTVar
and aretry
, so the above two solutions are operationally completely equivalent.