Monadsはどのようなプログラミング上の問題を解決しますか?[閉まっている]


14

私はモナドがどのように、何であるかを説明記事をたくさん読んだunitし、bindそれは目がいくつかのつまり完全に無視して、出血との奇妙なアナロジーに触れます(少なくとも私にとっては)それらのいくつかは、抽象ので圏論にまっすぐ急落仕事を、ブリトー、ボックスなど。

数週間の研究と多くの揚げたニューロンの後、(私は思う)モナドがどのように機能するかを理解しています。しかし、私の理解を逸するものがまだ1つあります。実際に触れている投稿はほとんどありません(IOと状態を除く)。

どうして?

モナドが重要なのはなぜですか?なぜそんなに重要なのですか?彼らが解決している問題は何ですか?これらの問題はMonadsでのみ解決できますか、それとも他の方法がありますか?


3
プログラムは大きく複雑です。それらを構造化する方法が必要です。多くの方法があります。モナドは1つです。矢印は1つです。ファンクターは1つです。オブジェクト、クラス、関数、メソッド、モジュール、特性、ミックスイン、パッケージは他にもあります。具体的な質問が何であるかは明確ではありません。プログラムを構成する必要がある理由をお尋ねですか?
ヨルグWミットタグ

1
@JörgWMittag:プログラムを構成する必要がある理由を私は尋ねていません。明らかに、大きな問題は小さな問題に分割され、それを解決してから組み合わせて、大きな問題の解決策を得ることができます。モナドが解決する問題を尋ねています。それですか?コードの構造化?それはすべて大騒ぎですか?たとえば、Haskellでは、これがI / Oの方法です。そこでは、モナドは、実際にはそうではないが純粋なもののように振る舞うふりです。私の質問はタイトルにあり、それをより明確な方法で述べる方法がわかりません。
ダミーミー



1
@RobertHarvey:追加した最初の2つのリンクも見つかりましたが、それらや他の投稿の回答のように、応答はMaybe、StateおよびIOモナドに直行し、すぐに例またはコードにジャンプし、「たくさんあります」 Monadsを使用して解決できる問題の一覧」。他の種類の問題はどれですか?私は同じ例を繰り返す代わりに実際に問題の根源(それらが何であれ)に行き、モナドがそれらを解決する方法と、他のものを使用するのではなく、なぜそれが最良の選択であるかを説明するより高いレベルの答えを探しています。フィードバックをありがとうございます。
ダミーミー

回答:


10

モナドは何も解決する必要ありません。彼らは特定のものをより単純にします。モナドを説明するとき、多くの人があまりにも抽象的で理論的になりすぎます。ほとんどの場合、モナドはプログラミングで繰り返し登場するパターンです。そのパターンを認識することで、コードを単純化し、特定の機能を再実装することを回避できます。

Haskellでは、具体的な観点から、モナドが有効にする最も目に見えるものはdo notationです。 Haskellや他の言語のリスト内包表記もモナドを大いに活用します。Control.Monadのようなライブラリを作成することもできます。

これらはすべて便利な単純化を提供し、1つのモナドに対して実装すると、すべてのモナドに対して自動的に取得されます。これが、コードの再利用が他のパラダイムよりも関数型プログラミングにとって非常に簡単な理由の1つです。


2
haskellモナドが有効にする最も目に見えるものは、実際に期待どおりに機能するIOエフェクトを簡単に作成できる方法だと実際に言います。モナドが私たちに何を与えるのか疑問に思う人は、ミランダを試してみるべきだと思います。ミランダは、Haskellが置き換えるように設計された言語であり、Haskellの経験がある人なら誰でも簡単に学習できるはずです。主な違いは、モナドIOを持たないことです。これにより、重要ではないプロジェクトでは、Haskellよりも言語の操作がはるかに難しくなります。
ジュール

はい、IOHaskellの最も有名なモナドですが、個々のモナドの例をリストしていませんでした。私はそれらが可能にする包括的な抽象化の例を挙げていました。たとえば、IOにモナドを使用することを最初に考えた人が、一般に良いアイデアだと思う理由を理解しようとしていました。
カールビーレフェルト

1
@Jules:または、Haskellの歴史を見てください。Monadsの前に、HaskellデザイナーはI / Oの基礎としてLazy StreamsとContinuationsを実験しましたが、どちらも使いにくいものでした。
ヨルグWミットタグ

5

特定のモナドを見て、どのモナドが解決するかを見ると理解しやすくなります。たとえば、Haskellの場合:

  • IO:IOを型システムで表すことができるため、IOを実行する関数から純粋な関数を明確に分離できます。

  • リスト:リストの理解と非決定的な計算を行うことができます。

  • たぶん:nullのより良い代替手段であり、C#のnull合体演算子に匹敵するものをサポートしています。

  • Parsec:パーサーを作成するための便利なDSL。

したがって、個々のモナドはすべて非常に有用であるため、個々のモナドの理論的根拠を見るのは簡単です(願っています)。しかし、彼らが解決する問題もまったく異なっており、一見すると、それらはすべてチェーン操作のロジックに関連していることを除いて、あまり共通しているようには見えません。モナドは、このようなさまざまなツールを構築できるため便利です。

上記の例はモナドなしで実装できますか?確かにアドホックな方法で実装できますが、言語にモナドを組み込むことで、doすべてのモナドで機能する-notationのような直接言語サポートが可能になります。


2

それは混乱になることの一つは、そのような「人気」の機能であるbind<*>指向実践しています。しかし、概念を理解するには、最初に他の機能を見るほうが簡単です。モナドは、他の関連する概念と比較して少し誇張されているため、際立っていることにも注意する価値があります。そこで、代わりにファンクターから始めます。

ファンクターは関数を提供します(Haskell表記)fmap :: (Functor f) => (a -> b) -> f a -> f b。つまりf、関数を持ち上げることができるコンテキストがあります。あなたが想像できるように、ほとんど何でもファンクターです。リスト、多分、いずれか、関数、I / O、タプル、パーサー...それぞれが値を表示できるコンテキストを表します。そのため、を使用するfmapか、インラインバリアントを使用して、ほぼすべてのコンテキストで機能する非常に汎用性の高い関数を作成できます<$>

コンテキストで他にやりたいことは何ですか?2つのコンテキストを組み合わせることができます。したがってzip :: [a] -> [b] -> [(a,b)]、たとえば次のような一般化を取得することができますpair :: (Monoidal f) => f a -> f b -> f (a,b)

しかし実際にはさらに便利なので、Haskellライブラリは代わりにを提供しますApplicative。これはFunctorand MonoidalとAndの組み合わせであり、Unit実際にコンテキストの「内部」に値を置くことができることを追加するだけですunit

作業中のコンテキストに関するこれら3つのことを述べるだけで、非常に汎用的な関数を作成できます。

Monadあなたはその上に述べることができるもう一つのことです。私が前に言及しなかったことは、2つのコンテキストを結合する2つの方法がすでにあるということです:pairそれらだけでなく、スタックすることもできます。例えば、リストのリストを持つことができます。I / Oコンテキストでの例は、ファイルから他のI / Oアクションを読み取ることができるI / Oアクションです。したがって、typeがありFilePath -> IO (IO a)ます。実行可能な関数を取得するために、そのスタックをどのように取り除くことができますIO aか?そこでMonads joinが登場し、同じタイプの2つのスタックされたコンテキストを組み合わせることができます。同じことはパーサーにも当てはまるかもしれません。たぶんbind、より実用的な方法です。join

したがって、モナドコンテキストは4つのものを提供するだけでよく、I / O、パーサー、障害などのために開発されたほぼすべての機械で使用できます。


1

Monadsを使用すると、コードを簡素化するだけでなく、さまざまな非純粋な計算を表現できます

  • ステートフル計算(モナド経由で状態を取得/設定)
  • I / O(ロギング、UI、ファイル、またはXのリストの作成/消費のみ)
  • また、「非線形」制御フロー(例外、多分など)

そして、重要なことは、純粋な言語構成に妥協することなく、よりクリーンな言語を取得することです


2
True-しかし、それはモナドの用途の一部にすぎません。内包表記をリストMaybeするか、外部の何かに関連していません。
ジャックB

downvotersがなぜそうしたのかを説明してくれると便利です。この答えには何の問題もありません。
ジュール

しかし、@ JacquesBはステートフルです。
ジュール

1
ただし、ワールドタイプ、一意性タイプ、線形タイプでも同様に行うことができます。
ヨルグWミットタグ

非決定性モナドとしての@Jules Listsはステートフルですか?「ステートフル」の定義を明確にできますか?
ジャック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.