可以在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发布于 2012-12-31 11:05:16
解决方案是将launchGhosts声明为
launchGhosts :: [[(String,String)]] -> IO (Buffer String)问题是您将launchGhosts声明为返回一个Buffer String,这是一个TVar [[(String, String)]]。因为launchGhosts使用do块,所以它的结果类型需要一个Monad实例,根据您的签名,该实例是TVar。这就是第一个错误所涉及的内容。
另一个问题是atomically的类型是STM a -> IO a,所以atomically newBuffer是一个IO something (实际的类型)。但是您在一个被声明为具有Buffer (即TVar)类型的do块中使用它,因此它也应该具有该类型(预期的类型)。这就是第二个错误的内容。
编辑:
为什么要更改computeBlock的类型签名?我从来没说过任何关于computeBlock的事。
https://stackoverflow.com/questions/14096954
复制相似问题