Haskell 初始化后返回TVar

Haskell 初始化后返回TVar,haskell,concurrency,Haskell,Concurrency,是否可以在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

是否可以在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
类型缓冲区a=TVar[(a,a)]]
newBuffer::STM(缓冲区a)
newBuffer=newTVar[]]
启动重影::[[(字符串,字符串)]]->缓冲区字符串
launchGhosts unblocked=do buff IO()
computeBlock buff=doi[[(a,a)]]->STM()
put buff x=do writeTVar buff x
get::Buffer a->STM[[(a,a)]]

get buff=do x解决方案是将
启动重影声明为

launchGhosts :: [[(String,String)]] -> IO (Buffer String)
问题是您将
launchGhosts
声明为返回一个
Buffer String
,这是一个
TVar[[(String,String)]]
。由于
launchGhosts
使用
do
块,因此其结果类型需要
Monad
实例,根据您的签名,它是
TVar
。这就是第一个错误的原因

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

编辑:


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

的事情。解决方案是将
启动重影声明为

launchGhosts :: [[(String,String)]] -> IO (Buffer String)
问题是您将
launchGhosts
声明为返回一个
Buffer String
,这是一个
TVar[[(String,String)]]
。由于
launchGhosts
使用
do
块,因此其结果类型需要
Monad
实例,根据您的签名,它是
TVar
。这就是第一个错误的原因

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

编辑:


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

当我收到IO类型的值时,我还能使用computeBlock的“get buff”吗?@conce我不知道你刚才问了什么。在computeBlock过程中,我使用的参数buff现在将是IO类型(缓冲字符串)(请参阅更新)。我还能用这个来读TVar吗(i@Consec否,
buff
仍然是一个
缓冲字符串
。您是否尝试使用更新的类型签名编译代码?是否存在编译错误?如果存在,是哪个?是否存在编译错误(请参阅问题的更新版本)我想这就是他们的原因。当我收到IO类型的值时,我还能使用computeBlock的“get buff”吗?@Concer我不知道你刚才问了什么。在computeBlock过程中,我使用的参数buff现在将是IO类型(缓冲字符串)(见更新)。我还能用它来读取TVar吗(i@Consec否,
buff
仍然是一个
缓冲字符串
。您是否尝试使用更新的类型签名编译代码?是否存在编译错误?如果存在,是哪一个?是的,存在编译错误(请参阅问题的更新版本),我认为这就是原因。
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
launchGhosts :: [[(String,String)]] -> IO (Buffer String)