1

新しく作成された TVar を do ブロックで返すことは可能ですか? 私はこのコードを使用してこれを実装しようとしました:

type Buffer a = TVar [[(a,a)]]

newBuffer :: STM (Buffer a)
newBuffer = newTVar [[]]

launchGhosts :: [[(String,String)]] -> Buffer String
launchGhosts unblocked = do buff <- atomically newBuffer
                            atomically $ put buff unblocked
                            return buff


computeBlock :: Buffer String -> IO()
computeBlock buff = do i <- atomically $ get buff
                       putStrLn $ show i

put :: Buffer a -> [[(a,a)]] -> STM ()
put buff x = do writeTVar buff x

get :: Buffer a -> STM [[(a,a)]]
get buff = do x <- readTVar buff
              return x

これにより、共有メモリを初期化し、プログラム内の別の場所で使用できるようになります。メモリの初期化を分離したい主な理由は、メモリを何度も初期化せずに並行関数を複数回呼び出すことです。

型チェッカーは、次の 2 つのエラーをスローします。

pacman.hs:65:29:
No instance for (Monad TVar)
  arising from a do statement
Possible fix: add an instance declaration for (Monad TVar)
In a stmt of a 'do' block: buff <- atomically newBuffer
In the expression:
  do { buff <- atomically newBuffer;
       atomically $ put buff unblocked;
       computeBlock buff;
       return buff }
In an equation for `launchGhosts':
    launchGhosts unblocked
      = do { buff <- atomically newBuffer;
             atomically $ put buff unblocked;
             computeBlock buff;
             .... }

pacman.hs:65:37:
    Couldn't match expected type `TVar t0' with actual type `IO a0'
    In the return type of a call of `atomically'
    In a stmt of a 'do' block: buff <- atomically newBuffer
    In the expression:
      do { buff <- atomically newBuffer;
           atomically $ put buff unblocked;
           computeBlock buff;
           return buff }

問題が何であるか、またはこのコードの背後にあるアイデアを実装する別の方法を知っている人はいますか?

アップデート:

launchGhosts :: [[(String,String)]] -> IO(Buffer String)
launchGhosts unblocked = do buff <- atomically newBuffer
                            atomically $ put buff unblocked
                            return buff


computeBlock :: IO(Buffer String) -> IO()
computeBlock buff = do i <- atomically $ get buff
                       putStrLn $ show i

アップデート:

pacman.hs:71:46:
Couldn't match expected type `Buffer a0'
            with actual type `IO (Buffer String)'
In the first argument of `get', namely `buff'
In the second argument of `($)', namely `get buff'
In a stmt of a 'do' block: i <- atomically $ get buff
4

1 に答える 1

1

解決策は、次のように宣言することlaunchGhostsです

launchGhosts :: [[(String,String)]] -> IO (Buffer String)

launchGhosts問題は、を返すことを宣言したことです。Buffer StringこれはTVar [[(String, String)]]です。ブロックをlaunchGhosts使用するため、その結果タイプのインスタンスが必要です。これは、署名によるとです。これが最初のエラーです。doMonadTVar

もう1つの問題はatomically、タイプSTM a -> IO aがであるためatomically newBufferIO something(実際のタイプ)もです。ただし、 (つまり)タイプdoを持つように宣言されたブロックで使用しているため、そのタイプ(予期されるタイプ)も持つ必要があります。これが2番目のエラーです。BufferTVar

編集:

なぜ型アノテーションを変更したのcomputeBlockですか?私はについて何も言わなかったcomputeBlock

于 2012-12-31T03:05:16.230 に答える