State モナド内にステートフルな関数がたくさんあります。プログラムのある時点で、いくつかの IO アクションが必要になるため、次のようなタイプのペアを取得する StateT 内に IO をラップしました。
mostfunctions :: State Sometype a
toplevel :: StateT Sometype IO a
物事を単純にするために、IO コンテキストを関数のメイン セットに渡したくありません。また、それらをモナド スタック型でラップすることは避けたいと思います。しかし、トップレベル関数からそれらを呼び出すには、リフトに似たものが必要ですが、内側のモナドから値を持ち上げようとしているわけではありません。むしろ、私は StateT モナドの状態を State モナドの同等のものに変換したいと考えています。これを行うために、私は次のものを持っています:
wrapST :: (State Sometype a) -> StateT Sometype IO a
wrapST f = do s <- get
let (r,s2) = runState f s
put s2
return r
これは、次のようなものをインターリーブするために使用されます。
toplevel = do liftIO $ Some IO functions
wrapST $ Some state mutations
liftIO $ More IO functions
....
かなり明白なコード ブロックのように思えるので、この関数には標準名があり、標準ライブラリのどこかに既に実装されているのだろうか? 説明を簡潔にしようとしましたが、明らかにこれは、スタックから 1 つのトランスフォーマーを取り出し、ラップされた値をトランスフォーマー型のいとこに変換し、スタック内で下のモナドをスキップし、結果を終わり。