11

haskell の stm ライブラリには、次の型シグネチャを持つ関数があります。

alwaysSucceeds :: STM a -> STM ()

Haskell の STM について私が理解していることから、STM 計算の実行中に何かが「うまくいかない」(その用語を大まかに使用すると) 3 つの方法があります。

  1. 読み取られた TVar の値は、別のスレッドによって変更されます。
  2. ユーザー指定の不変条件に違反しています。retryこれは通常、最初からやり直すために呼び出すことによってトリガーされるようです。これにより、スレッドが効果的にブロックされ、読み取りセットの TVar が変更されると再試行されます。
  3. 例外がスローされます。呼び出しthrowSTMが原因です。これは、トランザクションが再開されないため、最初の 2 つとは異なります。代わりに、エラーが伝播され、プログラムがクラッシュするか、IO モナドでキャッチされます。

これらが正確である場合 (正確でない場合は教えてください)、何ができるのか理解alwaysSucceedsできません。そのalways上に構築されているように見える関数は、次のように記述しなくてもよいようですalwaysSucceeds

--This is probably wrong
always :: STM Bool -> STM ()
always stmBool = stmBool >>= check

のドキュメントにalwaysSucceedsは次のように書かれています:

alwaysSucceeds は、alwaysSucceeds に渡されたとき、現在のトランザクションの最後、および後続のすべてのトランザクションの最後に true でなければならない新しい不変条件を追加します。これらのポイントのいずれかで失敗した場合、違反しているトランザクションは中止され、不変条件によって発生した例外が伝播されます。

しかし、引数は型STM a( では多態的a) であるため、トランザクションが返す値を意思決定のどの部分にも使用することはできません。つまり、先ほど挙げたさまざまなタイプの障害を探しているようです。しかし、そのポイントは何ですか?STM モナドはすでに失敗を処理しています。この関数でラップすると、どのように影響しますか? また、型の変数がa削除されて、結果が になるのはなぜSTM ()ですか?

4

1 に答える 1

8

の特別な効果はalwaysSucceeds、実行された場所で失敗をチェックする方法ではなく (「不変」アクションを単独で実行しても同じことを行う必要があります)、トランザクションの最後に不変チェックを再実行する方法です。

基本的に、この関数は、上記の (2) のようにユーザー指定の不変条件を作成します。これは、現在だけでなく、後のトランザクションの最後にも保持する必要があります。

「トランザクション」はSTMモナド内のすべてのサブアクションを参照するのではなく、 に渡される結合されたアクションを参照することに注意してくださいatomically

は利便性のためだけに削除されているので、アクションをに渡す前に(たとえば、 で)a変換する必要はありません。戻り値は、後で繰り返されるチェックではとにかく役に立ちません。STM ()voidalwaysSucceeds

于 2014-09-07T05:17:43.660 に答える