2017-07-09 4 views
-2

Je suis nouveau chez haskell et stm et je voulais faire un simple rwlock. J'ai d'abord créé les 4 fonctions principales (wlock, wunlock, rlock, runlock) qui nécessitent 2 TVar Integer: le nombre de threads de lecture et d'écriture.Constructeur TVar? Je ne peux pas obtenir un TVar

À ce stade, je ne peux pas l'utiliser comme prévu. Je tente de compiler comme ce

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

Wich est bien sûr laid, mais il fonctionne (ne sais pas pourquoi, car retourne atomiquement IO (TVar a) au lieu de TVar a)

Ce que je veux:

Je J'essaie de le rendre meilleur en cachant les valeurs. J'ai lu quelque part que les monades pourraient être la voie à suivre, mais je ne les ai pas encore étudiées. Je tente plutôt de faire une nouvelle rwlock de type que

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

et un constructeur, donc je peux faire quelque chose comme ceci:

import Rwlock 

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

où le lecteur appellera rlock a et écrivain wlock a.

Le problème:

Je ne peux pas faire le constructeur. Voilà ce que j'essayer (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}-} 

Mais constructeur tvár n'est pas exporté, et rien ne retourne un tvár. Je ne sais pas pourquoi le premier bloc de code fonctionne quand je fais wlock v1 v2, mais ce n'est pas le cas.

et (B):

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

Ici rwlock n'a pas un problème, mais comme je veux, au lieu de rwlock retourne instruction Do IO(), et je ne peux pas trouver comment faire il :(

Quelqu'un peut-il me dire la façon de le faire Merci d'avance

+0

Voir aussi https://stackoverflow.com/questions/4235348/converting-io-int-to-int –

Répondre

4

Allouer serrures IO le travail à faire, et vous ne pouvez pas contourner cette difficulté admettre donc dans le type de votre action?..:

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

Puis, en main, vous pouvez écrire quelque chose comme ceci:

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