STモナド
state-transformer monad
mutableな変数を純粋な計算で扱うためのモナド
破壊的代入を関数内部に閉じ込める
型の定義
hsnewtype ST s a = ST (State# s -> (# State# s, a #))
s
幽霊型
a
STモナドに含まれる値の型
ST.hsrunST :: (forall s. ST s a) -> a
JSで普通にできるような再代入変数の扱いを冗長にエミュレートしてる感じ
jslet n = 0
for(let i = 0; i <= 10; i++) {
n += i;
}
console.log(n); // 55
hsimport Control.Monad.ST
st :: ST s Integer
st = do
n <- newSTRef 0 -- 再代入するための変数の定義
forM_ [1..10] $ \i -> do
modifySTRef n (+i) -- 再代入
readSTRef n -- 読み出し
main :: IO ()
main = print $ runST st -- 55
参考
パフォーマンスが重要な処理を書く時に使う
mutableな値を扱っているが、runSTによって得られるものはIOとは関連がないので純粋
変数への参照をdo式の外に持ち出せない
これによって安全になっている
method
IO、IORefと比較して
IOモナドを制限したもの
メモリ操作に限定したもの
runSTに依って、モナドから値を取り出せう
これはIO系モナドにはできない
IO型は、ST型の一般化になっている
STの型定義
hsnewtype ST s a = ST (State# s -> (# State# s, a #))
Hsnewtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
s
に RealWorld
を指定したものがIO
hsnewtype IO a = ST RealWolrd a
Stateモナドと比較して
メモリ割り当てを状態として捉えるStateモナド
参考
IOモナドとの比較など