モナドから学ぶためのクリエイティブな使い方を探しています。AI などでモナドが使用されていることをどこかで読んだことがありますが、モナドの初心者であるため、その方法がわかりません。
ソース コードと使用例へのリンクを含めてください。標準モナドはありません。
Phil Wadler はモナド に関する多くの論文を書いていますが、最初に読む論文は非常に楽しく、どのプログラマにもアクセスできるものです。それは関数型プログラミングの本質と呼ばれています。このペーパーには、ソース コードと使用例が含まれています。
私の個人的なお気に入りは確率モナドです。Sungwoo Parkの博士論文を見つけることができれば、ロボット工学の興味深いサンプル コードが多数掲載されています。
LogicT (公平な操作と枝刈りを伴うバックトラック モナド トランスフォーマー)もあります。
たとえば、無限回成功する計算を簡単に結合 (インターリーブ) できるようにするなど、公正な論理和の構成要素があるため、AI 検索アルゴリズムにとって優れた価値があります。
その使用法は、ICFP'05 論文Backtracking, Interleaving, and Terminating Monad Transformers で説明されています。
ブログA Neighborhood of Infinityで興味深い高度なモナドを見つけることができます。Vector Space Monadと、その有理もつれ記述への使用に注目できます。残念ながら、ここで説明できるほどよく理解できていないと思います。
私のお気に入りのモナドの1つは、MartinEscardoの検索モナドです。パッケージ内のハッキングでinfinite-search
見つけることができます。
これは、タイプの要素のセットに対する「検索関数」のモナドです。a
つまり、(a -> Bool) -> Maybe a
(指定された述語に一致するセット内の要素を検索する)。
確率と確率的プロセスをモデル化するために使用されるモナドに関する一連の記事をここで読んでください: http://www.randomhacks.net/articles/2007/03/03/smart-classification-with-haskell (前/次の部分へのリンクをたどってください)
モナドの興味深い使い方の 1 つは構文解析です。Parsecは標準的な例です。
x86 マシン コードの実行時生成用パッケージであるHarpyは、コード生成モナドを使用します。説明から:
これは、コードバッファの処理、バイナリデータの発行、再配置などのすべての詳細を処理する結合されたリーダー状態例外モナドです。
モジュール Harpy.X86CodeGen のすべてのコード生成関数はこのモナドに存在し、そのエラー報告機能とモナドによって維持される内部状態を使用します。
ライブラリのユーザーは、モナドを介してユーザー環境とユーザー状態を渡すことができます。この状態は内部状態から独立しており、コード生成操作全体で独自の状態を維持するために、高レベルのコード生成ライブラリによって使用される場合があります。
このパターンは珍しいことではないと思うので、これは特に興味深い例だと思いました。(株式) 市場データ フィードから受信したメッセージに基づいてアプリケーションの内部メッセージのセットを生成するために、非常によく似たものを自分で発明しました。それ自体では状態を保持しない単純な操作を構成しながら、フレームワークにさまざまな「グローバル」な事柄を追跡させることは、非常に快適な方法であることが判明しました。
私は、モナドを介して渡すこともできるユーザー状態 (私は「サブ状態」と呼んでいます) を持つという彼のアイデアをさらに一歩進めました: 私は、モナドの実行中に状態を切り替えて復元するためのメカニズムを持っています:
-- | Given a generator that uses different substate type, convert it
-- to a generator that runs with our substate type. As well as the
-- other-substate-type generator, the caller must provide an initial
-- substate for that generator and a function taking the final substate
-- of the generator and producing a new substate of our type. This
-- preserves all other (non-substate) parts of the master state touched
-- by the generator.
--
mgConvertSubstate :: MsgGen msg st' a -> st' -> (st' -> st) -> MsgGen msg st a
これは、短期間必要な独自の状態を持つコンビネータのサブグループに使用されます。これらは、それを呼び出したジェネレーターの状態については何も知らずに、状態だけで実行されます (これにより、モジュール化が促進されます)。ただし、生成されたメッセージの現在のリストや、現在の警告またはエラーのセット、および制御フロー (つまり、すべてのアボートが上向きに流れるようにする)。
他の回答でまだ言及されていないいくつかのモナドをリストしたいと思います。
Omega
モナドを使用して、結果の無限リストを生産的にトラバースできます。比較:
>>> take 10 $ liftM2 (,) [0..] [0..]
[(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(0,9)]
>>> take 10 $ runOmega $ liftM2 (,) (each' [0..]) (each' [0..])
[(0,0),(0,1),(1,0),(0,2),(1,1),(2,0),(0,3),(1,2),(2,1),(3,0)]
もう少し高度なWeightedSearch
モナドを使用すると、計算に重みを割り当てて、より低い重みの計算結果が最初に出力に現れるようにすることもできます。
便利なThese
データ型は にMonad
似ていますEither
が、むしろエラーを蓄積することができます。このパッケージは、に基づくMonadChronicle
クラスとChronicleT
モナド トランスフォーマーThese
も定義します。