fonction de contrôle Haskell STM renvoyant undefined
Question
Y at-il une bonne raison pour laquelle la fonction check
dans la bibliothèque de Contol.Concurent.STM
est de type Bool -> STM a
et retourne undefined
sur le succès plutôt que d'avoir le Bool -> STM ()
type? La façon dont il est mis en œuvre le contrôleur de type va compiler un système politique ne bloquent la fin avec check foo
seulement à l'échec à l'exécution avec *** Exception: Prelude.undefined
.
La solution
On dirait qu'il est une définition de l'espace réservé pour un GHC PrimOp , comme le seq _ y = y
« définition » qui sera remplacé par le compilateur avec le code de mise en œuvre primitive réelle. PrimOp mise en œuvre de check
prend une expression et ajoute à une liste globale des invariants comme décrit dans la section STM papier invariants.
Voici un exemple de super-modifié de ce arrangé papier en fonction du nouveau type de check
:
import Control.Concurrent.STM
data LimitedTVar = LTVar { tvar :: TVar Int
, limit :: Int
}
newLimitedTVar :: Int -> STM LimitedTVar
newLimitedTVar lim = do
tv <- newTVar 0
return $ LTVar tv lim
incrLimitedTVar :: LimitedTVar -> STM ()
incrLimitedTVar (LTVar tv lim) = do
val <- readTVar $ tv
let val' = val + 1
check (val' <= lim)
writeTVar tv val'
test :: STM ()
test = do
ltv <- newLimitedTVar 2
incrLimitedTVar ltv -- should work
incrLimitedTVar ltv -- should work still
incrLimitedTVar ltv -- should fail; we broke the invariant
De façon réaliste, il serait utile d'invariants assert sur l'état partagé où l'affirmation ne peut être un signe d'une incohérence temporaire. Vous voudrez peut-être alors une nouvelle tentative dans l'attente de cette invariant devenir encore vrai finalement, mais étant donné que cet exemple serpente rupture de façon permanente l'invariant, il appelle juste retry
pour toujours et semble se bloquer. Consultez le papier pour bien meilleurs exemples, mais gardez à l'esprit que le type a changé depuis sa publication.