なぜモナドが必要なのか?質問する

なぜモナドが必要なのか?質問する

私の謙虚な意見では、有名な質問に対する答えは「モナドとは何か?」特に最も投票数の多いものは、モナドがなぜ本当に必要なのかを明確に説明せずに、モナドとは何かを説明しようとしています。モナドは問題の解決策として説明できるのでしょうか?

ベストアンサー1

なぜモナドが必要なのでしょうか?

  1. 関数のみを使用してプログラミングしたいのです。(結局は「関数型プログラミング(FP)」です)。
  2. さて、最初の大きな問題があります。これはプログラムです:

    f(x) = 2 * x

    g(x,y) = x / y

    最初に何を実行するかをどのように指定すればよいでしょうか?関数のみを使用して、順序付けられた関数のシーケンス (つまりプログラム)をどのように形成できるでしょうか?

    解決法:関数を作成しますg。最初に、次に としたい場合はf、 と記述しますf(g(x,y))。この方法では、「プログラム」も関数になります。OKmain = f(g(x,y))ですが...

  3. さらに問題があります。一部の関数は失敗する可能性があります(つまりg(2,0)、0 で割る)。FPには「例外」はありません(例外は関数ではありません)。どうすれば解決できるでしょうか?

    解決策:関数が 2 種類のものを返すようにします。つまり、(2 つの実数から 1 つの実数への関数) ではなく、 (2 つの実数から (実数または何もない) への関数)g : Real,Real -> Realを許可します。g : Real,Real -> Real | Nothing

  4. しかし、関数は(より単純にするために)1 つのものだけを返す必要があります。

    解決策: 返される新しいタイプのデータ、つまり、実数または単に何も囲まない「ボクシング タイプg : Real,Real -> Maybe Real」を作成しましょう。したがって、次のようになります。OK ですが...

  5. ではf(g(x,y))fは を使用する準備ができていません。また、を使用するためMaybe Realに、接続できるすべての関数を変更する必要はありません。gMaybe Real

    解決策:関数を「接続」/「作成」/「リンク」するための特別な関数を用意しましょう。こうすることで、舞台裏で、1 つの関数の出力を次の関数に供給するように調整できます。

    この場合は、 (にg >>= f接続/構成) です。の出力を取得して検査し、 の場合は を呼び出さずにを返すか、逆に、ボックス化された を抽出してそれをフィードします。(このアルゴリズムは、 型に対するの実装にすぎません)。また、 は「ボクシング タイプ」ごとに1 回だけ記述する必要があることに注意してください(異なるボックス、異なる適応アルゴリズム)。gf>>=gNothingfNothingRealf>>=Maybe>>=

  6. この同じパターンを使用して解決できる他の多くの問題が発生します。1. 「ボックス」を使用してさまざまな意味/値をコード化/保存し、そのような関数にそれらの「ボックス化された値」を返すようにします。2.の出力を の入力に接続するためのgコンポーザー/リンカーを用意します。これにより、何も変更する必要がなくなります。g >>= fgff

  7. この技術を使用して解決できる注目すべき問題は次のとおりです。

    • 関数のシーケンス(「プログラム」)内のすべての関数が共有できるグローバル状態を持つ:ソリューションStateMonad

    • 私たちは「不純な関数」、つまり同じ入力に対して異なる出力を生成する関数を好みません。したがって、これらの関数をマークして、タグ付き/ボックス化された値 (モナド) を返すようにします。IO

完全に幸せです!

おすすめ記事