Pregunta

¿Hay una buena razón por la cual el check función en el Contol.Concurent.STM La biblioteca tiene tipo Bool -> STM a y devuelve undefined sobre el éxito en lugar de tener el tipo Bool -> STM ()? La forma en que se implementa el comprobador de tipo compilación de Polity compilará un bloque de bloque de hacer con check foo solo para fallar en tiempo de ejecución con *** Exception: Prelude.undefined.

¿Fue útil?

Solución

Parece que es una definición de marcador de posición para un GHC Primop, como la "definición" seq _ y = y Eso es reemplazado por el compilador con el código de implementación primitivo real. los Implementación primaria de check toma una expresión y la agrega a una lista global de invariantes como se describe en el Papel de invariants stm.

Aquí hay un ejemplo súper confundido modificado de ese papel para adaptarse al nuevo tipo 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

Siendo realistas, esto sería útil para afirmar a los invariantes en el estado compartido, donde la falla de la afirmación podría ser un signo de una inconsistencia temporal. Es posible que desee volver a intentar con la expectativa de que ese invariante se vuelva verdadero nuevamente eventualmente, pero dado que este ejemplo termina rompiendo permanentemente al invariante, solo llama retry por siempre y parece colgar. Consulte el documento para ver ejemplos mucho mejores, pero tenga en cuenta que el tipo ha cambiado desde su publicación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top