2011-12-03 17 views
9

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

+0

Esta es una buena pregunta; parece que el 'cheque 'descrito en el [documento de invariantes de STM] (http://research.microsoft.com/en-us/um/people/simonpj/papers/stm/stm-invariants.pdf) ahora se llama' alwaysSucceeds'. No está claro para mí lo que hace la 'verificación' actual. – acfoltzer

+0

Sí, no tengo idea de cuál podría ser el propósito de tenerlo así. Un poco curioso ahora. –

+0

'check b = if b then return undefined else retry' Reclamo que debería leer' check b = if b then return() else retry' –

Respuesta

5

Parece que es una definición de marcador de posición para GHC PrimOp, como la "definición" seq _ y = y que se reemplaza por el compilador con el código de implementación primitivo real. El PrimOp implementation of check toma una expresión y la agrega a una lista global de invariantes como se describe en el STM invariants paper.

Aquí está un ejemplo súper artificial modificado a partir de ese papel para adaptarlas 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 

realista, esto sería útil para afirmar invariantes en estado compartido en su defecto la afirmación podría ser una señal de una incoherencia temporal. Quizás desee volver a intentarlo con la expectativa de que ese invariante vuelva a ser cierto nuevamente con el tiempo, pero como este ejemplo termina rompiendo permanentemente el invariante, simplemente llama al retry para siempre y parece colgarse. Consulte el documento para obtener ejemplos mucho mejores, pero tenga en cuenta que el tipo ha cambiado desde su publicación.

+0

Entiendo cómo funciona el cheque. No entiendo por qué está escrito de tal manera que 'check True >> = writeTVar t' pasará la verificación de tipo, pero causará un error de tiempo de ejecución. Afirmo que el código anterior debe fallar verificación de tipo a menos que 't' es el tipo más bien inútil' TVar() '. –

+0

Ahhh, pensé que la pregunta era más en la dirección de "si esto es todo el código, ¿cuál es el punto?" Estoy de acuerdo en que parece que el tipo debería ser 'Bool -> STM()'. – acfoltzer

Cuestiones relacionadas