STモナド
state-transformer monad
mutableな変数を純粋な計算で扱うためのモナド
破壊的代入を関数内部に閉じ込める
元になった論文はLazy functional state threads
hackage
便利関数などはData.STRefに定義されている
型の定義
code:hs
newtype ST s a = ST (State# s -> (# State# s, a #))
s
state thread
幽霊型
a
STモナドに含まれる値の型
runST
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 -- 再代入するための変数の定義
forM_ 1..10 $ \i -> do
modifySTRef n (+i) -- 再代入
readSTRef n -- 読み出し
main :: IO ()
main = print $ runST st -- 55
参考
/mrsekut-book-4774192376/204 (5.6 ST sモナド)
#WIP
パフォーマンスが重要な処理を書く時に使う
mutableな値を扱っているが、runSTによって得られるものはIOとは関連がないので純粋
変数への参照をdo式の外に持ち出せない
これによって安全になっている
method
IO、IORefと比較して
IOモナドを制限したもの
どの面で #??
メモリ操作に限定したもの
と、/mrsekut-book-4774192376/204 (5.6 ST sモナド)に書いているがピンときていない
runSTに依って、モナドから値を取り出せう
これはIO系モナドにはできない
https://qiita.com/7shi/items/2e9bff5d88302de1a9e9#ioモナドとの関係
IO型は、ST型の一般化になっている
STの型定義
code:hs
newtype ST s a = ST (State# s -> (# State# s, a #))
IOの型定義 ref
code:Hs
newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
sにRealWorldを指定したものがIO
code:hs
newtype IO a = ST RealWolrd a
Lazy functional state threadsにもそういう話が書いているらしい
IORefとSTRefの使い分け
https://uehaj.hatenablog.com/entry/2014/01/29/110222
Stateモナドと比較して
メモリ割り当てを状態として捉えるStateモナド
STモナドとStateモナドのAPIの比較
幽霊型とrank-2 typesで型安全なスコープを作る
A Logical Relation for Monadic Encapsulation of State
参考
Haskell 状態系モナド 超入門 - Qiita
IOモナドとの比較など
http://wwwa.pikara.ne.jp/okojisan/haskell-sort/haskell-stmonad.html
https://shinharad.hateblo.jp/entry/2019/12/04/000050
https://github.com/shiatsumat/wiwinwlh-jp/wiki/高度なモナド#st-monad
http://nnwww.hatenablog.com/entry/2017/07/08/014126
https://xtech.nikkei.com/it/article/COLUMN/20080603/305833/
https://xtech.nikkei.com/it/article/COLUMN/20080630/309793/
https://wiki.haskell.org/Monad/STMonad/ST - HaskellWiki