Haskell STM Check関数は未定義で返されます
質問
その理由はありますか check
の関数 Contol.Concurent.STM
ライブラリにはタイプがあります Bool -> STM a
と返品 undefined
タイプを持つのではなく成功します Bool -> STM ()
?タイプチェッカーの実装方法 check foo
実行時にのみ失敗する *** Exception: Prelude.undefined
.
解決
それはのためのプレースホルダーの定義のように見えます GHC Primop, 、「定義」のように seq _ y = y
これは、実際のプリミティブ実装コードでコンパイラに置き換えられます。 のPrimop実装 check
式を取り、で説明されているように、それを不変剤のグローバルリストに追加します STM不変紙.
これは、新しいタイプの新しいタイプに合うようにその論文から修正された超対照的な例です 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
永遠に、そしてぶら下がっているように見えます。より良い例については、論文をチェックしてください。ただし、このタイプは出版以来変更されていることに留意してください。
所属していません StackOverflow