TVar构造函数?我不能得到一个TVar

时间:2017-07-09 22:43:40

标签: haskell stm tvar

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

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

v1 <- atomically(newTVar 0);
v2 <- atomically(newTVar 0);
wlock v1 v2 -- wlock :: TVar Integer -> TVar Integer -> IO ()

当然是丑陋的,但它有效(不确定为什么因为原子地返回IO (TVar a)而不是TVar a

我想要的是什么:

我试图通过隐藏价值来改善它。我在某地读过monad可能是要走的路,但我还没有研究它们。相反,我尝试将新类型Rwlock设为

data Rwlock = Rwlock {  readCant :: TVar Integer 
    ,writeCant :: TVar Integer
}

和构造函数,所以我可以这样做:

import Rwlock

do{
    a = rwconst;
    forkIO(reader a);
    forkIO(writer a);
}

读者将致电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}-}

但TVar构造函数未导出,并且没有任何内容返回TVar。我不知道为什么第一个代码块在我wlock v1 v2时会起作用,但这样做却没有。

和(B):

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

这里Rwlock没有问题,但是do语句返回IO(),而不是我想要的Rwlock,我找不到怎么做:(

任何人都可以告诉我这样做的方法吗?提前谢谢。

1 个答案:

答案 0 :(得分:4)

分配锁需要做IO,你无法解决这个问题。因此,请在行动类型中承认:

rwconst :: Integer -> IO Rwlock
rwcost n = do
    rcount <- newTVarIO 0
    wcount <- newTVarIO 0
    return Rwlock { readCant = rcount, writeCant = wcount, maxLectores = n }

然后,在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