1. ホーム

[解決済み】なぜモナドが必要なのか?

2022-04-17 01:21:55

質問

私の考えでは、有名な質問に対する答えは モナドとは何ですか? 特に、最も多く投票されたものは、モナドとは何かを明確に説明することなく、モナドを説明しようとしています。 モナドが本当に必要な理由 . 問題解決として説明できるのか?

どのように解決するのか?

なぜモナドが必要なのか?

  1. プログラミングをしたい 関数だけを使う . ("関数型プログラミング(FP)"結局のところ)。
  2. では、最初の大問題です。これはプログラムです。

    f(x) = 2 * x

    g(x,y) = x / y

    どうすれば 何が最初に実行されるか ? 関数の順序を決めるにはどうしたらよいのでしょうか? プログラム ) 関数しか使わない ?

    解決策 関数の合成 . もし、最初に g で、次に f と書くだけです。 f(g(x,y)) . このように、quot;the program" は関数でもあります。 main = f(g(x,y)) . OK、でも...

  3. その他の問題:いくつかの機能 に失敗する可能性があります。 (例 g(2,0) , 0で割る)。私たちは 例外はありません。 をFPで表現することができます(例外は関数ではありません)。どのように解決するのでしょうか?

    解決方法 では 関数が2種類のものを返せるようにする の代わりに g : Real,Real -> Real (二つの実数から一つの実数への関数)を、次のようにしましょう。 g : Real,Real -> Real | Nothing (2つの実数から(実数または何もない)への関数)。

  4. しかし、関数は(よりシンプルにするために)以下のものしか返さないはずです。 一つのこと .

    解決策:返すデータの種類を新しく作ってみよう、" ボックス型 実体を包むか、あるいは単に無である。したがって、私たちは、次のようにすることができます。 g : Real,Real -> Maybe Real . よし、でも.

  5. にはどうなるのでしょうか? f(g(x,y)) ? f を消費する準備ができていない。 Maybe Real . で接続できるすべての関数を変更することは避けたい。 g を消費するように Maybe Real .

    解決策:Let's 関数の接続/合成/リンクのための特別な関数があります。 . そうすれば、裏側で、ある関数の出力を次の関数の出力に適応させることができます。

    私たちの場合 g >>= f (接続/合成 g から f ). 私たちは >>= を取得する g の出力を検査し、万が一それが Nothing を呼び出さないだけです。 f を返し Nothing または、逆に、ボックス化された Real を送り f を付けています。(このアルゴリズムは、単に >>= に対して Maybe タイプ)を使用します。また、以下の点に注意してください。 >>= は、次のように書かなければなりません。 一度だけ ボクシングタイプごとに(異なるボックス、異なる適応アルゴリズム)。

  6. 1.異なる意味や値をコード化・保存するために"box"を使用し、以下のような機能を持たせる。 g これらの"boxed values"を返すようにする。2. コンポーザー/リンカーを持つ g >>= f の接続を支援するために g の出力と f の入力を変更する必要はありません。 f を使用します。

  7. この手法で解決できる顕著な問題点としては

    • 一連の関数(プログラム)の中のすべての関数が共有できるグローバルな状態を持つこと:解決策 StateMonad .

    • 私たちは、「不純な関数」を好みません。 異なる に対する出力は 同じ を入力します。そこで、これらの関数をマークして、タグ付け/ボックス化された値を返すようにしましょう。 IO モナドを使用します。

トータルハピネス!