私は現在、Haskell でいくつかのトランザクション メモリ ベンチマークに取り組んでおり、トランザクション内で乱数を利用できるようにしたいと考えています。現在、ここからランダムモナド/モナドトランスフォーマーを使用しています。次の例では、整数を含む TVar の配列と、配列内の 10 個の tvar をランダムに選択してインクリメントするトランザクションがあります。
tvars :: STM (TArray Int Int)
tvars = newArray (0, numTVars) 0
write :: Int -> RandT StdGen STM [Int]
write 0 = return []
write i = do
tvars <- lift tvars
rn <- getRandomR (0, numTVars)
temp <- lift $ readArray tvars rn
lift $ writeArray tvars rn (temp + 1)
rands <- write (i-1)
lift $ return $ rn : rands
私の質問は、「これがこれを行うための最良の方法ですか?」ということだと思います。逆の方法、つまりランダムモナドを STM モナドに持ち上げる方がより自然で効率的であるように思われます。各トランザクションは多くの STM 操作を実行し、ランダム操作はほとんど実行しません。それぞれlift
がある程度のオーバーヘッドを追加すると思います。だけにする方が効率的ではないでしょうかlift
ランダムな計算を行い、STM の計算はそのままにしておきますか? これを行っても安全ですか?STM モナド トランスフォーマーを定義すると、STM モナドで得られる優れた静的分離特性が損なわれるようです (つまり、IO を STM モナドに持ち上げることはできますが、トランザクションが中止された場合に IO アクションを元に戻すことについて心配する必要があります。問題数)。モナド変換子に関する私の知識はかなり限られています。トランスを使用する場合のパフォーマンスと相対的なオーバーヘッドに関する簡単な説明をいただければ幸いです。