見出し画像

💎関数型言語とモナドの理解

モナドはファンクターの一種である。値を包み込む性質をもつ  ファンクターとmap関数と引数に使う高階関数


配列オブジェクトにマッピングが追加されたことで、ECMAScript5では基本的な配列タイプが充実した関手(Functor)に変わり、関数型プログラミングがより身近なものになりました。

https://ascii.jp/elem/000/000/270/270129/

そしてモナド

関数型プログラミングにおいて、モナドはプログラムの断片(関数)を組み合わせ、その戻り値を計算を追加した型で包む構造を持つソフトウェアデザインパターンである。モナドは、包むモナド型の定義に加えて、モナド型で値を包む演算子と、モナド型の値を出力する関数(これらをモナド関数と呼ぶ)をまとめて合成する演算子を定義している。汎用言語では、モナドを使用して、一般的な操作に必要な定型的なコードを削減する(未定義値や誤りやすい関数への対処、帳簿コードのカプセル化など)。関数型言語では、モナドを使用して、複雑な関数列を、制御フローや副作用を抽象化した簡潔なパイプラインに変換する。

https://en.wikipedia.org/wiki/Monad_(functional_programming)

モナドの概念も用語も元々はカテゴリ理論に由来し、モナドは付加的な構造を持つファンクタとして定義される[a]。1980年代後半から1990年代前半に始まった研究により、モナドが一見バラバラに見えるコンピュータサイエンスの問題を統一された機能モデルの下に置くことができることが立証された。また、カテゴリ理論はモナドの法則として知られるいくつかの形式的要件を提供しており、これはあらゆるモナドが満たすべきものであり、モナドコードの検証に使用することができる。

https://en.wikipedia.org/wiki/Monad_(functional_programming)

モナドの一例として、Maybe型がある。未定義のnull結果は、多くの手続き型言語が対処するための特別なツールを提供しない、特に苦痛な点の一つで、未定義の値を扱うためにnullオブジェクトパターンを使用するか、操作ごとに無効な値をテストするチェックが必要である。これはバグの原因となり、エラーを優雅に処理する堅牢なソフトウェアを構築することを難しくしている。Maybe型は、結果の2つの状態を明示的に定義することで、プログラマにこうした未定義の可能性がある結果を扱わせる。

https://en.wikipedia.org/wiki/Monad_(functional_programming)

これは本で読んだ

ファンクタとOPTIONタイプ、関数オブジェクト(C++)の違い

関数型プログラミングにおいて、ファンクタはカテゴリ理論からの定義に着想を得たデザインパターンであり、汎用型の構造を変えずに内部の関数を適用することを可能にするものである。

https://en.wikipedia.org/wiki/Functor_(functional_programming)

プログラミング言語(特に関数型プログラミング言語)および型理論において、オプション型または多分型は、オプションの値のカプセル化を表す多相型である。これは、空のコンストラクタ(しばしば None または Nothing と名付けられる)、または元のデータ型をカプセル化するコンストラクタで構成されています。

https://en.wikipedia.org/wiki/Option_type

javaではOptional(=Maybeなのかな)

Optional は、null ではないオブジェクトを格納するために使用されるコンテナオブジェクトです。Optionalオブジェクトは、値が存在しないNULLを表現するために使用されます。このクラスは、NULL値をチェックする代わりに、'available' や 'not available' として値を処理するコードを容易にする様々なユーティリティ・メソッドを持っています。これはJava 8で導入され、GuavaのOptionalと同じようなものです。

https://www.tutorialspoint.com/java8/java8_optional_class.htm

コンピュータプログラミングにおいて、関数オブジェクト[a]とは、あるオブジェクトを通常の関数と同じように、通常は同じ構文(関数にもなりうる関数パラメータ)で呼び出したり、呼び出したりできるようにする構成要素のことである。関数オブジェクトはしばしばファンクタと呼ばれる

https://en.wikipedia.org/wiki/Function_object
// comparator predicate: returns true if a < b, false otherwise
struct IntComparator
{
  bool operator()(const int &a, const int &b) const
  {
    return a < b;
  }
};

int main()
{
    std::vector<int> items { 4, 3, 1, 2 };
    std::sort(items.begin(), items.end(), IntComparator());
    return 0;
}

ソート系の関数のコールバック引数、PHPとかPERLにもあった気がするがそれもすべてファンクタと呼んで問題ない。


std::sort() 関数にコールバックを提供する構文は同じですが、関数ポインタの代わりにオブジェクトが渡されることに注意してください。呼び出されると、コールバック関数は他のメンバ関数と同様に実行され、オブジェクトの他のメンバ(データまたは関数)に完全にアクセスできるようになります。も

https://amzn.to/3P5qT3u


jQueryのオブジェクトはモナド

jQueryのオブジェクトはモナドであり、そのメソッドはファンクタである。実際には、エンドファンクターと呼ばれる特殊なタイプのファンクターである。エンドファンクターは入力と同じカテゴリを返すファンクターで、つまりF :: jQueryの各メソッドはjQueryオブジェクトを受け取り、jQueryオブジェクトを返すので、メソッドを連結することができ、それらはjFunc :: jquery-obj -> jquery-objの型シグネチャを持つことになる。

https://rutlib5.com/book/4162/p/89

D3.jsはmonadic

レイアウトのようにクロージャを使うものは、多少モナド的(monadic)です(モナドとは呼ばないけど)。モナドは状態をカプセル化するもので、それをデータに対して実行することで何かを得ることができます。
モナドはデータをあるコンポーネントから別のコンポーネントに渡す方法を決定し、(D3)クロージャはそれを全く行いません。

https://stackoverflow.com/questions/27609016/is-the-d3-object-a-monad

クロージャという言葉がよく使われるように、クロージャは単なる関数(またはコードのブロック)で、データの一部のように扱うことができ、他の関数などに渡すことができます。モナドは、(おおざっぱに言うと)関数を順番に連結できるコンテキストのようなもので、ある関数から次の関数へのデータの渡し方を制御します。

https://stackoverflow.com/questions/790719/what-is-the-difference-between-a-monad-and-a-closure
https://amzn.to/3C5JLuU


関数型プログラミングでよく使われるモナドには以下のものがあります:

  1. Maybeモナド (または Optional モナド) - 値が存在するかもしれない、または存在しないかもしれない状況をモデル化します。例えば、Haskellでは `Maybe` 型があり、`Just x` または `Nothing` と表現されます。

  2. リストモナド - 複数の計算可能な結果を表します。リストモナドを使用すると、リストの各要素に対して操作を適用し、その結果を新しいリストに平滑化することができます。

  3. IOモナド - 入出力操作を安全に扱うためのモナドで、副作用を持つ操作を純粋関数型の文脈で扱うことができます。例えば、Haskellでファイル操作や画面出力を行うときに使われます。

  4. 状態モナド (State Monad) - 状態を持つ計算をカプセル化します。これにより、状態を変更する関数を連鎖させて状態の変遷をモデル化することができます。

  5. エラーモナド (または Either モナド) - 成功または失敗のどちらかを表す計算をモデル化します。Haskellでは `Either` 型が使われ、`Right x` で成功を、`Left e` でエラーを表します。

これらのモナドは、それぞれ異なる種類の計算を抽象化し、エラーハンドリング、状態管理、非同期処理などをより安全かつ表現力豊かに扱うために設計されています。

お願い致します