質問

その理由はありますか 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 永遠に、そしてぶら下がっているように見えます。より良い例については、論文をチェックしてください。ただし、このタイプは出版以来変更されていることに留意してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top