15

私は、「モナド」という言葉がやや一貫性のない方法で使用されているように見えることに気付きました. これは、世の中に出回っているモナドのチュートリアルの多く (ほとんどではないにしても) が、モナドを自分で理解し始めたばかりの人々 (例: 核廃棄物の宇宙服のブリトー) によって書かれているためであると私は信じるようになりました。過負荷/破損のようなものになっています。

特に、「モナド」という用語は、Maybe、List、IO などの型の個々の値に適用できるのか、それとも「モナド」という用語は本当に型自体にのみ適用されるべきなのか疑問に思っています。

これは微妙な違いであるため、類推するとより明確になるかもしれません。数学では、リング、フィールド、グループなどがあります。これらの用語は、個々の要素ではなく、それらに対して実行できる操作とともに、値のセット全体に適用されます。たとえば、整数は (加算、否定、および乗算の操作と共に) リングを形成します。「整数は環」とは言えますが、「5 は環」とは言えません。

では、「はモナドである」と言えますかJust 5、それとも「5 は環である」と言うのと同じくらい間違っていますか? Maybe私は圏論を知りませんが、「モナドです」ではなく、「モナドです」と言うのが本当に意味があるという印象を受けていますJust 5

4

5 に答える 5

19

「モナド」(および「ファンクター」)は、値を表すものとして一般的に誤用されています。モナド、ファンクター、モノイド、アプリケーションファンクターなどの値はありません。タイプとタイプコンストラクター(より高い種類のタイプ)のみが可能です。「リストはモノイドである」、「関数はモナドである」など、または「この関数はモナドを引数として取る」と聞いたとき(そしてそうなるでしょう)、信じないでください。話者に、「Haskellsクラスが値ではなく(高階型を含む)を分類することを考えると、どの値もモノイド(またはモナドまたは...)になることができますか?」と尋ねます。リストはモノイド(など)ではありません。List aは。

私の推測では、この一般的な誤用は、型クラスではなく値クラスを持つ主流の言語に起因しているため、習慣的で無意識の値クラスの考え方が潜入していると思います。

言語を正確に使用するかどうかが重要なのはなぜですか?私たちは言語で考え、言語を介して理解を構築し、伝えるからです。したがって、明確な考えを持つためには、明確な言葉を使う(またはいつでもできる)ことが役立ちます。

「私たちの言語の怠惰さは、私たちが愚かな考えを持つことを容易にします。要点は、プロセスが可逆的であるということです。」-ジョージ・オーウェル、政治と英語

編集:これらの発言は、圏論のより一般的な設定ではなく、Haskellに適用されます。

于 2012-06-21T16:52:25.800 に答える
11

ListはモナドでList aあり、型であり[]List a(型の要素) です。

技術的には、モナドは余分な構造を持つファンクターです。Haskell では、Haskell 型のカテゴリからそれ自体へのファンクタのみを使用します。

したがって、特に型を取り、別の型を返す「関数」です( kind を持ちます* -> *)。

ListState sMaybeなどはモナドです。Statekind を持っているので、モナドではありません* -> * -> *

(余談ですが、混乱させるために、モナドは単なる関手であり、部分的に順序付けられた集合 A を自分自身に与えると、それはカテゴリを形成し、 Hom(a, b) = { 1 element } if a <= b and Hom(a , b) = それ以外の場合は空. 任意の増加関数 f : A -> A はファンクタを形成し、モナドは x <= f(x) および f(f(x)) <= f(x) を満たす関数です。したがって、 f(f(x)) = f(x) -- ここでのモナドは技術的には「A -> A の要素」です。クロージャ演算子も参照してください。)

(余談 2: あなたは数学をある程度知っているように見えるので、圏論について読むことをお勧めします。とりわけ、代数構造がモナドから生じると見なすことができることがわかります。Dan Piponi による優れたブログのこの優れたブログ エントリを参照してください。ティーザー用。)

于 2012-06-18T19:55:59.997 に答える
4

正確には、モナドは圏論からの構造です。直接コードに対応するものはありません。簡単にするために、モナドの代わりに一般的な関手について話しましょう。Haskell の場合、おおざっぱに言えば、ファンクターは型のクラスから型のクラスへのマッピングであり、最初のクラスの関数を 2 番目のクラスの関数にもマップします。インスタンスは、マッピング関数へのFunctorアクセスを提供しますが、ファンクターの概念を直接キャプチャしません。

ただし、インスタンスで言及されている型コンストラクターFunctorは実際のファンクターであると言っても過言ではありません。

instance Functor Tree

この場合Treeはファンクタです。ただし、Tree型コンストラクターであるため、同時にファンクターを作成する両方のマッピング関数を表すことはできません。関数をマップする関数は と呼ばれfmapます。したがって、正確に言いたい場合は、タプル(Tree, fmap)がファンクターであり、fmapが特定のfmapfromTreeFunctorインスタンスであると言わなければなりません。便宜上、これをTreeファンクタと呼びます。これは、対応するfmapものがそのFunctorインスタンスから続くためです。

ファンクターは常に kind の型であることに注意してください* -> *。はファンクターMaybe Intではありません – ファンクターはMaybeです。また、人々はよく「状態モナド」について話しますが、これも不正確です。 Stateインスタンスでわかるように、無限に多くの状態モナドのファミリー全体です。

instance Monad (State s)

すべての型について、(種類の)s型コンストラクター状態モナドであり、多くのモナドの 1 つです。State s* -> *

于 2012-06-18T20:35:17.967 に答える
2

では、「ちょうど 5 はモナドである」と言えますか、それとも「5 は環である」と言うのと同じくらい間違っていますか?

あなたの直感はまさに正しいです。(または何でも)Intはそのまま(または何でも) です。値 ( 、など) は重要ではありません。RingAbelianGroupMaybeMonadFunctor5Just 5

代数では、整数の集合が環を形成すると言います。Haskell では、それは (非公式に)型クラスIntのメンバーであるRing、または (もう少し正式には) のRingインスタンスが存在すると言いますIntこの提案は楽しくて便利だと思うかもしれません。とにかく、モナドと同じ扱いです。

圏論はわかりませんが…

いずれにせよ、抽象代数について 1 つまたは 2 つのことを知っていれば、あなたは金持ちです。

于 2012-06-21T21:13:20.550 に答える
1

「ちょうど5はモナドのインスタンスである型です」と言うでしょう。

私がインスタンスという用語を使用するのは、Haskell で型クラスの実装を宣言する方法であり、Monad がその 1 つであるためです。

于 2012-06-16T22:01:38.600 に答える