TVar 构造函数?我找不到 TVar

Per*_*dor -1 haskell stm tvar

我是 Haskell 和 stm 的新手,我想制作一个简单的 rwlock。首先,我创建了 4 个主要函数(wlock、wunlock、rlock、runlock),需要 2 个 TVar 整数:读取线程和写入线程的数量。

此时我无法按预期使用它。我尝试这样编译

v1 <- atomically(newTVar 0);
v2 <- atomically(newTVar 0);
wlock v1 v2 -- wlock :: TVar Integer -> TVar Integer -> IO ()
Run Code Online (Sandbox Code Playgroud)

这当然很丑陋,但它有效(不知道为什么,因为原子地返回IO (TVar a)而不是TVar a

我想要的是:

我试图通过隐藏价值观来让它变得更好。我在某处读到单子可能是可行的方法,但我还没有研究它们。相反,我尝试创建一个新类型的 Rwlock 作为

data Rwlock = Rwlock {  readCant :: TVar Integer 
    ,writeCant :: TVar Integer
}
Run Code Online (Sandbox Code Playgroud)

和一个构造函数,所以我可以做这样的事情:

import Rwlock

do{
    a = rwconst;
    forkIO(reader a);
    forkIO(writer a);
}
Run Code Online (Sandbox Code Playgroud)

rlock a读者和作者都会打电话的地方wlock a

问题:

我无法创建构造函数。这就是我尝试的(忽略maxLectores

(A):

rwconst :: Integer -> Rwlock
rwconst n = Rwlock {readCant = TVar 0, writeCant = TVar 0, maxLectores = n}
{-rwconst n = Rwlock {readCant = atomically(newTVar 0), writeCant = atomically(newTVar 0), maxLectores = n}-}
Run Code Online (Sandbox Code Playgroud)

但 TVar 构造函数未导出,并且没有任何内容返回 TVar。我不知道为什么第一段代码在我这样做时有效wlock v1 v2,但这样就不行了。

以及(B):

rwconst :: Integer -> Rwlock
rwconst n = do
    a <- (atomically(newTVar 0));
    Rwlock {readCant = a, writeCant = a, maxLectores = n}
Run Code Online (Sandbox Code Playgroud)

这里Rwlock没有问题,但是do语句返回IO(),而不是我想要的Rwlock,我找不到如何做到这一点。

谁能告诉我该怎么做?提前致谢。

Dan*_*ner 6

分配锁需要进行 IO,这是无法回避的。因此,请在您的操作类型中承认这一点:

rwconst :: Integer -> IO Rwlock
rwcost n = do
    rcount <- newTVarIO 0
    wcount <- newTVarIO 0
    return Rwlock { readCant = rcount, writeCant = wcount, maxLectores = n }
Run Code Online (Sandbox Code Playgroud)

然后,在 中main,您可以编写如下内容:

main = do
    a <- rwconst 10
    forkIO (reader a)
    forkIO (writer a)
    -- and you should do something to wait for reader and writer to finish
Run Code Online (Sandbox Code Playgroud)