2011-12-05 9 views
15

一つは、右のモナドにlift操作に必要です。単一liftここと悪いありませんが、時にはこのように見えるの機能があります。入れ替えモナド変換スタック上の作業

fun = do 
    lift a 
    lift b 
    c 
    lift d 
    lift e 
    f 

私はこのように、この関数を記述できるようにしたいと思います:

fun = monadInvert $ do 
    a 
    b 
    lift c 
    d 
    e 
    lift f 

これは半分コード番号はliftです。コードがきれいになります。

質問:どのモナドについてmonadInvertが可能ですか?どのようにしてこの機能を作りますか?

ボーナスポイント:monad mの場合はMonadIOのインスタンスです。

この質問のタイトルは、順列について語っています。実際、モナドトランスフォーメータスタックの任意の順列にはどのように対処できますか?

+0

私は非常にあなたがすることができます疑いが(しかし、おそらくいくつかの邪悪なトリッキーを使用することができます)。タイプについて考えてみると、私には分かりません。 –

+0

シャベルレディソリューションではありませんが、[このペーパー](http://www.cs.umd.edu/~mwh/papers/monadic.pdf)の価値があります。 「私たちのアルゴリズムは、必要なバインド、ユニット、モナドからモナドへのモチーフを挿入して、プログラムのタイプが「 – acfoltzer

答えて

10

あなたは、Tom SchrijversとBruno OliveiraのMonads, Zippers and Views, Virtualizing the Monad Stackに興味があるかもしれません。

これはリフトを減らすことについてのあなたのポイントには言及しませんが、あなたの "モナド順列"問題への興味深いアプローチです。ここで

は抽象的です:

この作品はモナド スタックを仮想化するための2つの新技術採用することにより、変化に モナドのコンポーネントは、より再利用可能で堅牢な作りを目指して:モナドのジッパーとモナドの景色を。モナドジッパーコンクリートスタック内の特定の 層を無視することにより、仮想モナドスタックを作成モナド 変圧器です。モナドビューはモナドスタックの仮想化のための一般的なフレームワークを提供 :彼らは一歩 さらにモナドのジッパーを取り、他の仮想化し、幅広いとそれを統合します。例えば は、特定のビューは スタック内のモナドへのアクセス制限を可能にします。また、モナドビューは にコンポーネントによって使用されることができる特定の層にモナドスタックの にアクセスするためのコールバイリファレンスのようなメカニズムを提供します。これらの2つのメカニズムを使用すると、モナドスタックシェイプの観点からのコンポーネント要件 は、もはや文字通りコンクリートモナドスタックに反映される必要がなくなり、これらのコンポーネントを再利用可能にして変更に強くします。

16

まず、実際にはあまり持ち上げる必要はありません。以下のアイデンティティが保持モナド変圧器の場合:

lift c >>= lift . f = lift (c >>= f) 
lift c1 >> lift c2 = lift (c1 >> c2) 

それは書くことが珍しくありません。

x <- lift $ do 
    {- ... -} 

次がある:あなたがMTLまたはmonadLib(すなわち、のようなライブラリを使用する場合型クラスベースのライブラリの代わりに、変圧直接)、あなたが実際に直接、最も根本的なモナドにアクセスすることができます:あなたは本当にこの二点にもかかわらず、持ち上げるの多くを必要とする場合

c :: StateT MyState (ReaderT MyConfig SomeOtherMonad) Result 
c = do 
    x <- ask 
    y <- get 
    {- ... -} 

最後に、カスタムモナドを書いて検討すべきですまったく異なる抽象化を使用することさえできます。状態モナドの代わりにステートフルな計算にオートマトンの矢印を使用しています。

+1

」になっているかどうかをチェックしますが、とにかく感謝しています。 a、b、cは2つの異なるモナドから来ているので、私は 'lift(a >> b >> c)'と書くことができないことに注意してください。 – Tener

1

私は何をdecribingしていることは常に最も内側のモナドであるIO、不可能であることをほとんど確信しています:マーティンGrabmüllerから

: ダウンhttp://www.grabmueller.de/martin/www/pub/

で入手可能なステップバイモナド変圧ステップ、このドキュメントでは、eval6でliftIOを呼び出してI/Oアクションを実行します。 この場合、なぜ持ち上げる必要がありますか? のIOクラスがないので、型をインスタンス化できます。そのため、I/Oアクションのために、我々は一般的に内側に

コマンドを送信するためにリフトを呼び出す必要があり 、IOよりも制限モナドのために、(このようなエラーや状態など)の順序はまだセマンティクスのために重要なので、あなた構文をより便利にするためにスタックの順序を変更することはできません。

Readerのように中央にあるいくつかのモナドについては、あなたの考えは明らかに不可能ではないようです。私はそれを書く方法を知らない。私はそれがタイプクラスCentralMonadであると思いますReaderTは、いくつかの実装とのインスタンスです...

関連する問題