15

私が見つけたモナド変換子の問題の 1 つは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

この質問のタイトルは、順列について語っています。実際、モナド変換スタックの任意の順列をどのように処理できますか?

4

3 に答える 3

16

まず第一に、実際にはそれほど持ち上げる必要はありません。モナド変換子の場合、次の恒等式が保持されます。

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

次のように書くことは珍しくありません。

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

次は: mtlmonadLibのようなライブラリ(つまり、トランスフォーマーの代わりに型クラス ベースのライブラリ) を使用すると、実際にはほとんどの基礎となるモナドに直接アクセスできます。

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

最後に、これらの 2 つの点にもかかわらず、本当に多くのリフティングが必要な場合は、カスタム モナドを作成するか、まったく異なる抽象化を使用することを検討する必要があります。状態モナドの代わりに、ステートフルな計算にオートマトンの矢印を使用していることに気づきました。

于 2011-12-05T10:28:31.513 に答える
10

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

これは、リフトを減らすことについてのあなたの主張には対応していませんが、「モナド順列」の問題に対する興味深いアプローチです。

要約は次のとおりです。

この作業は、モナド スタックを仮想化するための 2 つの新しい手法、モナド ジッパーとモナド ビューを採用することで、モナド コンポーネントをより再利用可能にし、変更に対して堅牢にすることを目的としています。モナド ジッパーは、具体的なスタック内の特定のレイヤーを無視して仮想モナド スタックを作成するモナド トランスフォーマーです。モナド ビューは、モナド スタック仮想化の一般的なフレームワークを提供します。モナド ジッパーをさらに一歩進めて、さまざまな他の仮想化と統合します。たとえば、特定のビューでは、スタック内のモナドへの制限付きアクセスが許可されます。さらに、モナドビューをコンポーネントで使用して、モナドスタックの特定のレイヤーにアクセスするための call-by-reference のようなメカニズムを提供できます。

于 2011-12-05T10:19:36.150 に答える
1

あなたが説明していることは、常に最も内側のモナドである IO には不可能であると確信しています。

Martin Grabmüller より: Monad Transformers Step by Step、 http ://www.grabmueller.de/martin/www/pub/ で入手可能

このドキュメントでは、eval6 で liftIO を呼び出して I/O アクションを実行します。この場合、なぜ持ち上げる必要があるのでしょうか。型をインスタンス化できる IO クラスがないためです。したがって、I/O アクションの場合、lift を呼び出してコマンドを内部に送信する必要があります。

一般に、IO よりも制限の少ないモナド (Error や State など) の場合、順序は依然としてセマンティクスにとって重要であるため、構文をより便利にするためだけにスタックの順序を変更することはできません。

Reader のような中心的なモナド (スタック内で交換するという点で) については、あなたのアイデアは明らかに不可能ではないようです。書き方がわからないけど。いくつかの実装を備えた、のインスタンスでCentralMonadある型クラスになると思います...ReaderT

于 2012-01-17T22:34:35.107 に答える