コモナドとは何ですか?


16

最近、私はモナドがどのように機能するかについての知識を払拭しています。私はまたの概念を導入してきた「Comonad」として記述され、モナドのデュアル。しかし、頭を包むことはできません。

モナドを理解するために、私は自分自身に類推しました:

モナドは、「表現のコンベアベルトを構築するための青写真」と見ることができます。

新しいMonad(新しい種類のコンベアベルトシステム)を定義するには、以下を定義する必要があります。

  1. コンベアベルトに何かを置く方法。たとえば、コンベアベルトを「開始」します。(unitまたはとして知られているreturn
  2. コンベアベルトの一部となるマシン(表現)をコンベアベルトに接続する方法。(joinまたはbindまたはとして知られてい>>=ます)。

(現在のコンベヤーベルトを取り出し、その内容物を捨て、として知られる新しいコンベヤーベルトを開始する3番目の操作がありますが、>>使用されることはほとんどありません。)

機械とコンベアが適切に連携するには、次のことを確認する必要があります。

  1. コンベアベルトに何かを置いて機械に通した場合、出力は手動で機械に通したときと同じになります。(左身元)
  2. 既存のコンベヤーベルトの間にコンベヤーベルトを配置する場合、コンベヤーベルトが上にあるコンベヤーベルトではなく、単一の長いコンベヤーベルトで終わる必要があります。 (正しいアイデンティティ)
  3. マシンAを手動で使用し、コンベヤーに接続されたBCを介して結果を渡す場合、またはコンベヤーに接続されたABを使用し、Cを介して結果を手動で渡す場合、出力は重要ではありません。つまり、((a >> = b)>> = c)は(a >> =(b >> = c))と同じである必要があります(結合性

最も単純なコンベアベルトは、単に入力を受け取り、常に次の式に進むものです。これが「パイプライン」です。

別の可能性は、値に対して何らかの条件が満たされた場合にのみ次のマシンを通過させることです。つまり、中間の式の一部で値が許可されていないものに変更された場合、残りの式はスキップされます。これがHaskellで 'Maybe'モナドが行うことです。

また、値をマシンに渡す前または後に、値に対して他の派手な条件付きコピー/変更ルールを実行できます。例:パーサー(ここで、式が「失敗」の結果を返す場合、式のの値が 出力として使用されます)。

もちろん、アナロジーは完全ではありませんが、モナドがどのように機能するかを大まかに表してくれることを願っています。

しかし、私はコモナドを理解するためにこの類推を頭に置くのに苦労しています。インターネット上で見つけたわずかな情報から、コモナドが定義していることを知っています。

  • extract、これはの逆ですreturn。つまり、Comonad から値を取得します。
  • duplicate、これはの逆のようなjoinものです。つまり、1つのComonadsから2つのComonadを作成します。

しかし、Comonadから抽出または複製しかできない場合、Comonadはどのようにインスタンス化できますか?そして、実際にどのように使用できますか?私はこの非常に素晴らしいプロジェクトそれについての話を見ましたが(残念ながらほとんど理解していませんでした)、機能のどの部分がComonadによって正確に提供されるのかわかりません。

コモナとは何ですか?彼らは何のために役立ちますか?どのように使用できますか?彼らは食用ですか?


2
「Comonadは、抽出または複製しかできない場合、どのようにインスタンス化できますか?」-私はあなたの質問に質問で答えます:値を持ち上げて計算をシーケンスすることしかできない場合、どのようにモナドを消費できますか?
ベンジャミンホジソン

1
モナドの「コンベヤーベルトの端にある機械」(とにかく:モナドについて話すとき、私がそのようなすべての類似点を見つけられない)IOは、Haskellランタイムシステムmainです。unsafePerformIOもちろん、もあります。Maybeモナドが「コンベアベルトの端にあるマシン」を持っていると考えたい場合は、を使用できますmaybe
ベンジャミンホジソン

1
しかし、説明を逆にすると、一連のcobindアプリケーションの開始時に共通の値を生成したい場合は、共通の内部表現で何か有用な機能を実行する必要があります。
ベンジャミンホジソン

2
comonadまたはモナドの特定のインスタンスは、明らかにタイプクラスを実装するために必要な以上の機能を持つことができます
jk。

2
カテゴリ理論的/数学的な側面からこの質問にアプローチしない場合、これが役立つとは限りませんが、コモナは逆ではなく、モナドの双対であると指摘したかったのです。
ヨルグW

回答:


11

コモナドは、モナドのように、カテゴリー理論の数学的構造です。共接頭辞は、あなたがそれを置くときに「逆数」を示すために非常に一般的です(純粋な数学者が単語の選択に同意するとは思わないが)。

カテゴリー理論にはcategories、があります。これは、objects(任意のタイプまたは性質の、内部構造は無関係です)のコレクションとarrows、これらのオブジェクトの間にあるものです。何かをカテゴリにするには、矢印がいくつかの法則(左/右の同一性と結合性)に従う必要がありますが、ここではそれはあまり重要ではありません。

今、カテゴリー理論は非常に抽象的であり、理解しにくく、広大です。すべてを理解するには多くの時間がかかります(正式には勉強していませんが、基本的なことしか知っていません)dual。基本的に、すべてのカテゴリについてopposite category、「すべての矢印を逆にする」だけで同じことを実行することにより、構築できます。これは非常に単純な定義ですが、要約するのは困難です。カテゴリCの何かの双対は、基本的に反対のカテゴリC_opの同じものです(まだ頭痛の種はありますか?)

とにかく、あるカテゴリーにモナドがあるなら(そしてカテゴリーは、例えば、オブジェクトがプログラミング言語の型であり、矢印が型の間の関数であるカテゴリーになることができます)、comonadは基本的に同じものです、あなただけ'すべての矢印を逆にしました(この場合、関数シグネチャを逆にするようなものです)。

もっと「ハンズオン」(SUPERないハンズオンはあるが)説明はで見つけることができ、このエリック・メイジャー、彼らは二重性の概念を議論し、どのようにエリックがために、「矢印を反転」について、行ってきましたされているブライアン・ベックマンの間に議論IEnumerable<T>するときC#でリアクティブフレームワークを作成し、IObservable<T>(私が知る限り、修正できてうれしい限り、基本的にはリストコモナドインスタンスです)。

ビデオで言及されているコマンドのもう1つの実用的な例はTask<T>、.NET のタイプです。ここTask<U> ContinueWith<U>(Func<Task<T>, U>)で、デュアルbind(またはSelectManyC#で呼び出される)


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.