TVar конструктор? Я не могу получить TVar

Я новичок в haskell и stm, и я хотел сделать простой рулок. Сначала я создал 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)

Что я хочу:

Я пытаюсь сделать это лучше, скрывая ценности. Я где-то читал, что монады могут быть подходящим способом, но я еще не изучал их. Вместо этого я пытаюсь сделать новый тип 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)

(А):

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, но так не бывает.

И (Б):

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

Здесь у Rwlock нет проблем, но оператор do возвращает IO() вместо Rwlock, как я хочу, и я не могу найти, как это сделать:(

Кто-нибудь может сказать мне, как это сделать? Заранее спасибо.

1 ответ

Решение

Выделение блокировок требует ввода-вывода, и вы не можете обойти это. Так что признай это в своем действии:

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
Другие вопросы по тегам