私は最初の定義には興味がありません-それらは実際のプログラムを書くのに役立ちません(私が間違っていると確信したら+1)。2番目の定義を理解するのを手伝ってください。map、filter、reduce は便利だと思います。これらを使用すると、より高いレベルでプログラミングを行うことができます。つまり、間違いが少なくなり、コードがより短く、より明確になります。
2 つの定義は基本的に同じものです。1つ目は正式な定義に基づいており、提供する例はプリミティブコンビネーターであり、可能な限り最小のビルディングブロックです。それらを使用すると、より洗練されたコンビネータを作成できる限り、実際のプログラムを作成するのに役立ちます。S や K のようなコンビネータを、仮想の「組み合わせコンピュータ」の機械語と考えてください。もちろん、実際のコンピューターはそのようには機能しないため、実際には通常、高レベルの操作を別の方法で舞台裏で実装することになりますが、概念的な基盤は、これらの高レベルの操作の意味を理解するための有用なツールです。オペレーション。
あなたが与える2番目の定義は、より非公式で、さまざまな方法で他の関数を組み合わせる高階関数の形で、より洗練されたコンビネーターを使用することに関するものです。基本的なビルディング ブロックが上記のプリミティブ コンビネータである場合、それらから構築されたものはすべて高階関数であり、コンビネータでもあることに注意してください。ただし、他のプリミティブが存在する言語では、関数であるか関数ではないかが区別されます。この場合、コンビネータは通常、非関数を操作するのではなく、一般的な方法で他の関数を操作する関数として定義されます。物事を直接機能させます。
マップ、フィルターなどのコンビネーターの例は何ですか?
リストするには多すぎます!どちらも、単一の値に対する動作を記述する関数を、コレクション全体に対する動作を記述する関数に変換します。エンドツーエンドで合成したり、引数を分割して再結合したりするなど、他の関数のみを変換する関数を使用することもできます。シングルステップ操作を、コレクションを生成または消費する再帰操作に変換するコンビネータを使用できます。または、他のあらゆる種類のことです。
プログラミング言語がよく実装するコンビネータは何ですか?
それによってだいぶ変わってきます。完全にジェネリックなコンビネータは比較的少なく、ほとんどは上記のプリミティブ コンビネータです。そのため、ほとんどの場合、コンビネータは使用されているデータ構造をある程度認識します (それらのデータ構造が他のコンビネータから構築されている場合でも)。通常、少数の「完全に汎用的な」コンビネータと、誰かが提供することを決定したさまざまな特殊なフォームがあります。(適切に一般化されたバージョンの) map、fold、および unfold で、必要なほとんどすべてを実行するのに十分な場合が、非常に多くあります。
コンビネータは、より優れた API を設計するのにどのように役立ちますか?
低レベルの詳細ではなく、高レベルの操作とそれらが相互作用する方法の観点から考えると、まさにあなたが言ったように.
コレクションに対する「for each」スタイルのループの人気について考えてみてください。これにより、コレクションの列挙の詳細を抽象化できます。ほとんどの場合、これらは単なる map/fold 操作であり、(組み込み構文ではなく) コンビネーターを作成することで、2 つの既存のループを複数の方法で直接組み合わせて、一方を他方の内側に入れ子にするなどのことができます。一連のコード全体をジャグリングするのではなく、コンビネータを適用するだけで、次々と実行します。
効果的なコンビネータを設計するにはどうすればよいですか?
まず、プログラムが使用するデータが何であれ、どのような操作が意味を持つかを考えてください。次に、これらの操作を一般的な方法で有意義に組み合わせる方法と、操作をより小さな断片に分割して結合する方法について考えます。主なことは、直接的なアクションではなく、変換と操作で作業することです。不透明な方法で複雑な機能を実行し、事前に消化された結果を吐き出すだけの関数がある場合、それでできることはあまりありません。最終結果は、コンビネータを使用するコードに任せてください。プロセスの開始または終了を期待するものではなく、ポイント A からポイント B に移動するものが必要です。
非関数型言語 (Java など) のコンビネーターと似ているものは何ですか? または、これらの言語はコンビネーターの代わりに何を使用していますか?
あははは。そもそもオブジェクトは本当に高次のものなので、おかしなことに、オブジェクトにはデータがありますが、多くの操作も実行されます。優れた OOP 設計を構成する要素の多くは、「オブジェクトは通常、データ構造ではなく、コンビネーターのように振る舞います。」
したがって、おそらくここでの最良の答えは、コンビネーターのようなものの代わりに、多くの getter および setter メソッドまたは public フィールドを持つクラスと、不透明で事前定義されたアクションを実行することで主に構成されるロジックを使用することです。