私はイェソドのモナドを深く掘り下げており、に遭遇しましMonadBaseControl
た。ハッキングドキュメントを見て、迷子になりました。誰かが解決しようとしている問題を教えてもらえますか?
2 に答える
Michael Snoymanは、実際にmonad-controlに関する小さなチュートリアルを作成しました:http ://www.yesodweb.com/book/monad-control
その記事の要点は次のとおりです。
あなたがこのコードを持っていると想像してください:
withMyFile :: (Handle -> IO a) -> IO a
withMyFile = withFile "test.txt" WriteMode
withMyFile
このタイプの任意の関数に適用して、適切Handle -> IO a
なIO a
値を取得できます。ただし、型の関数があり、型Handle -> ErrorT MyError IO a
の値を取得したい場合はどうなりErrorT MyError IO a
ますか?さて、基本的にはwithMyFile
、多くのラッピング/アンラッピングを組み込むために変更する必要があります。withMyFile
MonadBaseControlを使用すると、特定のモナドトランスフォーマーのように、アンラッピング(「実行」)を可能にする関数をいくらか「リフト」することができます。したがって、結果のコードは次のようになります。
useMyFileError :: (Handle -> ErrorT MyError IO ()) -> ErrorT MyError IO ()
useMyFileError func = control $ \run -> withMyFile $ run . func
これはパッケージmonad-controlに由来し、それを実装するモナドの代替(resp。 )操作をサポートすることによってMonadBase(またはMonadTrans)を拡張するタイプクラスのペアの1つです(もう1つはMonadTransControlです)。この拡張バージョンは、絶対ベースモナド(または即時ベースモナド)で単純なアクションを実行しなくなりましたが、代わりに、その時点でのベースモナド(またはモナド変換子)全体の状態を唯一のパラメーターとして取得し、前述のアクション。liftBase
lift
パッケージのドキュメントに記載されているように、この拡張機能は、これらの型クラスの残りのコンテンツとともに、、、などcatch
の関数を絶対ベースモナド(または即時ベースモナド)から持ち上げることができます。これは、単純なものでは不可能です。MonadBase(またはMonadTrans )に存在するスキーム。後者のペアでは関数の引数を持ち上げることができず、結果だけを持ち上げることができますが、monad -controlによるアプローチでは両方が可能です。alloca
forkIO
その結果、 MonadBaseControl (またはMonadTransControl)で使用できるモナドのセット(またはモナド変換子)は、MonadBase(またはMonadTrans )で使用できるモナドのセットの厳密なサブセットですが、前者のグループは同じ理由で、後者よりもはるかに強力です。