1

是否可以在 do 块中返回新创建的 TVar?我尝试使用以下代码来实现这一点:

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

这应该允许我初始化共享内存并在程序的另一个地方使用它。我想分离内存初始化的主要原因是多次调用并发函数,而不是一次又一次地初始化内存。

类型检查器会引发以下两个错误:

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为返回 a Buffer String,即 a TVar [[(String, String)]]。由于launchGhosts使用了一个do块,因此它的结果类型需要一个Monad实例,根据您的签名,它是TVar. 这就是第一个错误的含义。

另一个问题是atomically具有 type STM a -> IO a,因此atomically newBuffer是 an IO something(实际类型)。但是您在do声明为具有Buffer(ie TVar) 类型的块中使用它,因此它也应该具有该类型(预期类型)。这就是第二个错误。

编辑:

为什么要更改 的类型签名computeBlock?我从来没有说过任何关于computeBlock.

于 2012-12-31T03:05:16.230 回答