I'm new at Haskell and stm and I wanted to make a simple rwlock. First I created the 4 main functions (wlock, wunlock, rlock, runlock) that requires 2 TVar Integers: the amount of reading threads and writing threads.
At this point I can't use it as intended. I try to compile like this
v1 <- atomically(newTVar 0);
v2 <- atomically(newTVar 0);
wlock v1 v2 -- wlock :: TVar Integer -> TVar Integer -> IO ()
which of course is ugly, but it works (not sure why because atomically returns IO (TVar a)
instead of TVar a
)
What I want:
I'm trying to make it better by hiding the values. I read somewhere that monads might be the way to go, but I haven't study them yet. Instead, I try to make a new type Rwlock as
data Rwlock = Rwlock { readCant :: TVar Integer
,writeCant :: TVar Integer
}
and a constructor, so I can do something like this:
import Rwlock
do{
a = rwconst;
forkIO(reader a);
forkIO(writer a);
}
where reader will call rlock a
, and writer wlock a
.
The problem:
I can't make the constructor. This is what I try (ignore 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}-}
But TVar constructor is not exported, and nothing returns a TVar. I don't know why the first block of code works when I do wlock v1 v2
, but this way it doesn't.
And (B):
rwconst :: Integer -> Rwlock
rwconst n = do
a <- (atomically(newTVar 0));
Rwlock {readCant = a, writeCant = a, maxLectores = n}
Here Rwlock doesn't have a problem, but the do statement returns IO(), instead of Rwlock as I want, and I can't found how to do it.
Anyone can tell me the way to do it? Thanks in advance.