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 でこれらの共有変数 (ゴーストに格納されている) を使用します。

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 愛好家にとって問題にならないのか誰か知っていますか?

4

1 に答える 1

4

これらはリスト内の値であることに注意してください。これは[TVar (Maybe Ghost)']正しいタイプ、つまりsのリストであり、 s作成するアクションのリストを作成しているため、実際にはそうではないため、代わりにTVar持っていると思います。トランザクション内でそれを使用します。[STM (TVar (Maybe a0))']STMTVar

したがって、作成TVarアクションのリストがある場合は、それを、のリストを作成する単一のアクションsequenceに変換し、トランザクション内でバインドする(つまり、の代わりに使用する)か、でsを作成するためにも使用します。いずれにせよ、その値をバインドした結果は、おそらく必要なのリストになります。STM [(TVar (Maybe a0))']TVar<-letatomicallyTVarIOTVar

于 2013-01-03T00:23:00.463 に答える