I am using Transaction variables in haskell that I instantiate in a function and collect in a list and that I give to another function to write values in:
step player ghosts info = do let unblocked = allPaths (source info) (target info) (graph info)
buff <- atomically $ newTVar [[]]
atomically $ put buff unblocked
let create = do return newGhostVal
let ghosts' = zip (map (\g -> newGhostVal) ghosts) ghosts
mapM_ (\g -> forkIO(atomically $ moveGhost buff (fst g) (graph info) (snd g))) ghosts'
putStrLn "launched"
and I use these shared variables (stored in ghosts') in the function moveGhost:
moveGhost buff res graph ghost =
do notBlocked <- get buff
...
writeTVar buff notBlocked'
writeTVar res (Just ghost'')
return()
While I use the same strategy for both shared variables buff as res, I get an error for the use of Tvar res
:
Couldn't match expected type `TVar (Maybe Ghost)'
with actual type `STM (TVar (Maybe a0))'
Expected type: [(TVar (Maybe Ghost), Ghost)]
Actual type: [(STM (TVar (Maybe a0)), b0)]
In the second argument of `mapM_', namely ghosts'
In a stmt of a 'do' block:
mapM_
(\ g
-> forkIO
(atomically $ moveGhost buff (fst g) (graph info) (snd g)))
ghosts'
Does anybody know what the problem is with this TVar and why it isn't a problem for TVar buff?
Noting that these are values in a list, I would expect that [TVar (Maybe Ghost)']
is the correct type--that is, a list of TVar
s--and that you have [STM (TVar (Maybe a0))']
instead because you're creating a list of STM
actions that would create TVar
s, but not actually using that inside a transaction.
So, wherever you have that list of TVar
-creating actions, you'll want to do something like sequence
to turn that into STM [(TVar (Maybe a0))']
, a single action that creates a list of TVar
s, then either bind that inside a transaction (i.e., using <-
instead of let
) or use atomically
as well to create the TVar
s in IO
. Either way, the result of binding that value will be the list of TVar
s that you probably want.