2011-12-03 70 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