2011-12-03 50 views
9

为什么Contol.Concurent.STM函数库中的check函数的类型为Bool -> STM a并且成功返回undefined而不是类型Bool -> STM()有充分的理由吗?事情是这样实现的类型检查器政体编译DO块与check foo结束只有在运行时用*** Exception: Prelude.undefined失败。Haskell STM检查函数返回undefined

+0

这是一个很好的问题;这似乎是在[STM不变量纸]所述的'check'(http://research.microsoft.com/en-us/um/people/simonpj/papers/stm/stm-invariants.pdf)现在称为' alwaysSucceeds'。我不清楚目前的“检查”功能。 – acfoltzer

+0

是的,我不知道这样做的目的可能是什么。有点好奇。 –

+0

'检查B =若B则返回undefined别的retry'我要求它应该读作检查B =若B则返回()其他retry' –

回答

5

它看起来像是一个GHC PrimOp的占位符定义,就像编译器用实际原始实现代码替换的“定义”seq _ y = y一样。 PrimOp implementation of check接受一个表达式并将其添加到STM invariants paper中描述的全局不变量列表中。

下面是该文件修改的超人为的例子,以适应新类型的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 

现实,这将是断言共享状态不变有用的,失败的断言可能是一个迹象暂时的不一致。那么你可能要与不变成为实现再最终的期望,重试,但由于这个例子卷起永久打破不变的,它只是调用retry永远似乎挂起。查阅这篇论文可以找到更好的例子,但请记住,该类型自发布以来已经发生了变化。

+0

我了解如何检查工作。我不明白为什么它会以'check True >> = writeTVar t'这样的方式写入,通过类型检查,但会导致运行时错误。我声称上面的代码应该会失败,除非't'是相当无用的类型'TVar()'。 –

+0

啊,我想这个问题更多的是朝着这个方向发展,“如果这是所有的代码,那有什么意义?”我同意这种类型应该是'Bool - > STM()'。 – acfoltzer