0

我在haskell中使用事务变量,我在一个函数中实例化并收集在一个列表中,然后我给另一个函数写入值:

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"

我在函数 moveGhost 中使用这些共享变量(存储在 ghosts 中):

moveGhost buff res graph ghost =
             do notBlocked <- get buff
             ...
             writeTVar buff notBlocked'
             writeTVar res (Just ghost'')
             return()

虽然我对两个共享变量 buff 使用与 res 相同的策略,但使用时出现错误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'

有谁知道这个 TVar 的问题是什么以及为什么它不是 TVar buff 的问题?

4

1 回答 1

4

注意到这些是列表中的值,我希望这[TVar (Maybe Ghost)']是正确的类型 - 即TVars 的列表 - 而您拥有的是正确的类型,[STM (TVar (Maybe a0))']因为您正在创建一个创建s 的STM操作列表,但实际上并非如此在事务中使用它。TVar

所以,无论你有那个TVar创建动作的列表,你都会想做一些事情,比如sequence把它变成STM [(TVar (Maybe a0))'],一个创建TVars 列表的单个动作,然后在事务中绑定它(即,使用<-而不是let)或也可以用来atomically创建TVars in IO。无论哪种方式,绑定该值的结果都将是TVar您可能想要的 s 列表。

于 2013-01-03T00:23:00.463 回答