C++ में कार्यात्मक प्रोग्रामिंग: उन्नत स्तर
\n\nकार्यात्मक प्रोग्रामिंग (FP) एक प्रतिमान है जो गणना को गणितीय फलनों के मूल्यांकन के रूप में मानता है और परिवर्तनीय अवस्था और दुष्प्रभावों से बचता है। हालाँकि C++ पारंपरिक रूप से ऑब्जेक्ट-ओरिएंटेड और प्रक्रियात्मक प्रोग्रामिंग से जुड़ा है, आधुनिक मानकों (C++11 और उससे आगे) ने कार्यात्मक कोड लिखने के लिए शक्तिशाली उपकरण पेश किए हैं। इस लेख में, हम बुनियादी लैम्ब्डा से आगे बढ़कर उन्नत तकनीकों पर विचार करेंगे: फंक्शन कम्पोज़ीशन से लेकर मोनैड के अनुकरण तक।
\n\n1. फंक्शन कम्पोज़ीशन और पाइपलाइन
\n\nफंक्शन कम्पोज़ीशन दो या अधिक फलनों को मिलाकर एक नया फलन बनाने की प्रक्रिया है। C++ में इसके लिए लैम्ब्डा एक्सप्रेशन और टेम्पलेट का उपयोग करना सुविधाजनक है।
\n\n#include <iostream>\n#include <functional>\n#include <vector>\n#include <algorithm>\n\n// दो फलनों की संरचना के लिए टेम्पलेट\ntemplate<typename F, typename G>\nauto compose(F f, G g) {\n return [f, g](auto x) {\n return f(g(x));\n };\n}\n\n// उपयोग का उदाहरण\nint main() {\n auto addTwo = [](int x) { return x + 2; };\n auto multiplyByThree = [](int x) { return x * 3; };\n\n // संरचना: पहले multiplyByThree, फिर addTwo\n auto composed = compose(addTwo, multiplyByThree);\n\n std::cout << composed(5) << std::endl; // (5*3) + 2 = 17\n\n // std::ranges के साथ पाइपलाइन प्रसंस्करण (C++20)\n std::vector<int> numbers = {1, 2, 3, 4, 5};\n auto result = numbers\n | std::views::filter([](int n) { return n % 2 == 0; })\n | std::views::transform([](int n) { return n * n; });\n\n for (int n : result) {\n std::cout << n << " "; // 4 16\n }\n return 0;\n}\n\n\nstd::views (C++20) के साथ पाइपलाइन मध्यवर्ती कंटेनर बनाए बिना परिवर्तनों की श्रृंखला बनाने की अनुमति देती है, जो एक क्लासिक कार्यात्मक दृष्टिकोण है।
2. करीइंग (Currying) और आंशिक अनुप्रयोग
\n\nकरीइंग एक ऐसे फलन का रूपांतरण है जो कई तर्क लेता है, फलनों के अनुक्रम में, जिनमें से प्रत्येक एक तर्क लेता है। आंशिक अनुप्रयोग तर्कों के एक भाग को स्थिर करता है।
\n\n#include <iostream>\n#include <functional>\n\n// करीड जोड़ फलन\nauto curriedAdd = [](int a) {\n return [a](int b) {\n return [a, b](int c) {\n return a + b + c;\n };\n };\n};\n\n// std::bind के साथ आंशिक अनुप्रयोग\nint multiply(int a, int b, int c) {\n return a * b * c;\n}\n\nint main() {\n // करीइंग का उपयोग\n auto add5 = curriedAdd(5);\n auto add5And3 = add5(3);\n std::cout << add5And3(2) << std::endl; // 10\n\n // std::bind के माध्यम से आंशिक अनुप्रयोग\n using namespace std::placeholders;\n auto multiplyBy2 = std::bind(multiply, _1, _2, 2);\n std::cout << multiplyBy2(3, 4) << std::endl; // 3*4*2 = 24\n\n // लैम्ब्डा के माध्यम से आंशिक अनुप्रयोग (C++14+ में अधिक मुहावरेदार)\n auto multiplyBy3 = [](int a, int b) { return multiply(a, b, 3); };\n std::cout << multiplyBy3(5, 6) << std::endl; // 5*6*3 = 90\n\n return 0;\n}\n\n\nकरीइंग विशेष रूप से उच्च-क्रम फलनों जैसे std::transform या std::accumulate के साथ काम करते समय उपयोगी है, जो "मौके पर" फलनों के विशेष संस्करण बनाने की अनुमति देता है।
3. फंक्टर, एप्लिकेटिव और मोनैड का अनुकरण
\n\nHaskell में, मोनैड दुष्प्रभावों के साथ काम करने के लिए एक शक्तिशाली पैटर्न है। C++ में, हम क्लास टेम्पलेट का उपयोग करके उनका अनुकरण कर सकते हैं। आइए एक सरल Maybe मोनैड (जो std::optional के समान है) पर विचार करें, लेकिन मोनैडिक संक्रियाओं के साथ।
#include <iostream>\n#include <functional>\n#include <optional>\n\n// Maybe मोनैड (std::optional पर आवरण)\ntemplate<typename T>\nclass Maybe {\n s