[英]return TVar after initialisation
Is it possible to return the newly created TVar in a do block? 是否可以在do块中返回新创建的TVar? I tried to implement this using this code:
我尝试使用以下代码实现此目的:
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
And this should allow me to initialize the shared memory and use it at another place in the program. 这应该允许我初始化共享内存,并在程序的其他位置使用它。 The main reason that I want to separate the memory initialization is to call the concurrent functions multiple times, without initialising the memory again and again.
我想要分离内存初始化的主要原因是多次调用并发函数,而不必一次又一次地初始化内存。
The type checker trows these two errors: 类型检查器引发以下两个错误:
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 }
Does anybody know what the problem is, or maybe another way to implement the idea behind this code? 有谁知道问题出在哪里,或者是实现此代码背后想法的另一种方式?
update: 更新:
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
update: 更新:
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
The solution is to declare launchGhosts
as 解决方案是将
launchGhosts
声明为
launchGhosts :: [[(String,String)]] -> IO (Buffer String)
The problem is that you declared launchGhosts
as returning a Buffer String
, which is a TVar [[(String, String)]]
. 问题是您声明
launchGhosts
返回了一个Buffer String
,它是TVar [[(String, String)]]
。 Since launchGhosts
uses a do
block, that requires a Monad
instance for its result type, which according to your signature is TVar
. 由于
launchGhosts
使用do
块,因此其结果类型需要一个Monad
实例,根据您的签名,该实例为TVar
。 This is what the first error is about. 这就是第一个错误。
The other problem is that atomically
has the type STM a -> IO a
, so atomically newBuffer
is an IO something
(the actual type). 另一个问题是,
atomically
类型为STM a -> IO a
atomically newBuffer
STM a -> IO a
,因此atomically newBuffer
是IO something
(实际类型)。 But you're using it in a do
block that was declared to have a Buffer
(ie TVar
) type, so it should have that type as well (the expected type). 但是您在声明为
Buffer
(即TVar
)类型的do
块中使用它,因此它也应该具有该类型(预期类型)。 This is what the second error is about. 这就是第二个错误所在。
Edit: 编辑:
Why did you change the type signature of computeBlock
? 为什么要更改
computeBlock
的类型签名? I never said anything about computeBlock
. 我从没说过关于
computeBlock
事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.