generated at
STモナド
state-transformer monad
mutableな変数を純粋な計算で扱うためのモナド
破壊的代入を関数内部に閉じ込める
元になった論文はLazy functional state threads


便利関数などはData.STRefに定義されている


型の定義
hs
newtype ST s a = ST (State# s -> (# State# s, a #))
s
幽霊型
a
STモナドに含まれる値の型


ST.hs
runST :: (forall s. ST s a) -> a


JSで普通にできるような再代入変数の扱いを冗長にエミュレートしてる感じ
js
let n = 0 for(let i = 0; i <= 10; i++) { n += i; } console.log(n); // 55
hs
import 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モナドを制限したもの
どの面で #??
メモリ操作に限定したもの
と、/mrsekut-book-4774192376/204 (5.6 ST sモナド)に書いているがピンときていない
runSTに依って、モナドから値を取り出せう
これはIO系モナドにはできない
IO型は、ST型の一般化になっている
STの型定義
hs
newtype ST s a = ST (State# s -> (# State# s, a #))
IOの型定義 ref
Hs
newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
s RealWorld を指定したものがIO
hs
newtype IO a = ST RealWolrd a
Lazy functional state threadsにもそういう話が書いているらしい



Stateモナドと比較して
メモリ割り当てを状態として捉えるStateモナド








参考
IOモナドとの比較など