web-dev-qa-db-ja.com

コモナドとは何ですか?それらはどのように役立ちますか?

最近、私はモナドがどのように機能するかについての私の知識を払いのけてきました。 'Comonad'の概念についても紹介しました。これはthe  モナドの双対。しかし、頭を巻くことはできません。

モナドを理解するために、私は自分自身のアナロジーを作りました:

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

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

  1. ベルトコンベアに何かを載せる方法。コンベヤベルトを「始動」します。 (unitまたはreturnとして知られています)
  2. コンベヤーベルトの一部となる機械(式)をコンベヤーベルトに接続する方法。 (joinまたはbindまたは>>=として知られています)。

(現在のコンベヤーベルトを取り、その内容を捨て、>>と呼ばれる新しいコンベヤーベルトを始動する3番目の操作がありますが、ごくまれに使用されます。)

機械とコンベヤが一緒に適切に機能するためには、次のことを確認する必要があります。

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

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

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

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

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

しかし、私はコモナドを理解するためにこのアナロジーを頭に向けるのに多くの問題を抱えています。私はインターネットで見つけた少量の情報から、コモナドが定義していることを知っています:

  • extractreturnの逆のようなものです。つまり、値はout Comonadになります。
  • duplicateは、joinの逆の一種です。つまり、単一のコマンドから2つのコマンドを作成します。

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

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

17
Qqwy

コモナードは、モナドと同様に、圏論における数学的構造です。コプレフィックスは、「逆行列」を表すのに非常に一般的です(ただし、純粋な数学者がWordの選択に同意することはないと思います)。

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

現在、カテゴリー理論は非常に抽象的であり、理解するのが難しく、広大です。すべてを確認するにはかなりの時間がかかります(そして、私は正式に研究していませんが、私はいくつかの基本を知っています)、dualと呼ばれる概念が使用されています。基本的に、すべてのカテゴリについて、同じことを行うだけで「すべての矢印を逆にする」ことで_opposite category_を構築できます。これは非常に単純な定義ですが、要約しようとするのは困難です。カテゴリCの何かの双対は、基本的に反対のカテゴリC_opのそれと同じです(まだ頭痛がしますか?)

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

より「実践的な」説明(SUPERの実践ではありません)は this で見つけることができます。ErikMeijerとBrian Beckmanの間で、二元性の概念とErikが「逆転」をどのように行ったかについて議論しています。反応型フレームワークを作成するときのC#の_IEnumerable<T>_の矢印」と_IObservable<T>_(これは私が知る限り、修正できて嬉しい限り、基本的にはリストのコマンドインスタンスです)。

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

11
sara

私の少しの理解から、コモナドはポストドキュメンテーションを行う Rube Goldberg machine です。

http://www.willamette.edu/~fruehr/haskell/evolution.html

...すみません、抵抗できませんでした。

4
dagnelies