STモナド
state-transformer monad
mutableな変数を純粋な計算で扱うためのモナド
破壊的代入を関数内部に閉じ込める
型の定義
code:hs
newtype ST s a = ST (State# s -> (# State# s, a #)) s
幽霊型
a
STモナドに含まれる値の型
code:ST.hs
runST :: (forall s. ST s a) -> a
JSで普通にできるような再代入変数の扱いを冗長にエミュレートしてる感じ
code:js
let n = 0
for(let i = 0; i <= 10; i++) {
n += i;
}
console.log(n); // 55
code:hs
import Control.Monad.ST
st :: ST s Integer
st = do
n <- newSTRef 0 -- 再代入するための変数の定義
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の型定義
code:hs
newtype ST s a = ST (State# s -> (# State# s, a #)) code:Hs
newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #)) sにRealWorldを指定したものがIO
code:hs
newtype IO a = ST RealWolrd a
Stateモナドと比較して
メモリ割り当てを状態として捉えるStateモナド
参考
IOモナドとの比較など