स्विफ्ट में कार्यात्मक प्रोग्रामिंग: उन्नत स्तर
स्विफ्ट को मूल रूप से एक बहु-प्रतिमान भाषा के रूप में डिज़ाइन किया गया था, जो इसे कार्यात्मक प्रोग्रामिंग की उन्नत तकनीकों को लागू करने के लिए एक आदर्श मंच बनाता है। इस लेख में, हम उन अवधारणाओं पर चर्चा करेंगे जो बुनियादी क्लोजर और map/filter/reduce से परे हैं - हम फंक्टर्स, मोनैड्स, फंक्शन कंपोज़िशन, करीइंग और मेमोइज़ेशन के बारे में बात करेंगे। ये उपकरण आपको iOS और macOS अनुप्रयोगों के लिए अधिक पूर्वानुमानित, परीक्षण योग्य और अभिव्यंजक कोड लिखने में मदद करेंगे।
फंक्टर्स और मोनैड्स: संदर्भों के साथ कार्य करना
फंक्टर एक प्रकार है जो map फ़ंक्शन को लागू करता है, जो संदर्भ के अंदर मान पर परिवर्तन लागू करने की अनुमति देता है। स्विफ्ट में, फंक्टर्स के क्लासिक उदाहरण Optional और Array हैं।
// फंक्टर Optionallet value: Int? = 42let result = value.map { $0 * 2 } // Optional(84)
// फंक्टर Arraylet numbers = [1, 2, 3]let doubled = numbers.map { $0 * 2 } // [2, 4, 6]मोनैड एक फंक्टर है जिसमें एक अतिरिक्त ऑपरेशन flatMap (या Haskell में >>=) होता है। यह नेस्टेड संदर्भों को "अनरैप" करने की अनुमति देता है। स्विफ्ट अंतर्निहित रूप से Monad प्रोटोकॉल के माध्यम से मोनैड्स का समर्थन करता है, लेकिन मुख्य प्रकार (Optional, Result, Async) इस तर्क को लागू करते हैं।
// मोनैड Optional: संभावित nil के साथ संचालन की श्रृंखलाfunc parseNumber(_ string: String) -> Int? { return Int(string) }func half(_ number: Int) -> Int? { return number % 2 == 0 ? number / 2 : nil }
let input = "42"let result = input.flatMap(parseNumber).flatMap(half) // Optional(21)
// त्रुटि प्रबंधन के लिए मोनैड Resultenum AppError: Error { case invalidInput }func safeDivide(_ a: Int, _ b: Int) -> Result<Int, AppError> { guard b != 0 else { return .failure(.invalidInput) } return .success(a / b)}
let divisionResult = safeDivide(10, 2).flatMap { safeDivide($0, 1) } // .success(5)उन्नत अनुप्रयोग: एसिंक्रोनस संचालन के साथ काम करने के लिए स्वयं का मोनैडिक प्रकार बनाना।
struct Async<T> { let run: (@escaping (T) -> Void) -> Void func map<U>(transform: @escaping (T) -> U) -> Async<U> { return Async<U> { callback in self.run { value in callback(transform(value)) } } } func flatMap<U>(transform: @escaping (T) -> Async<U>) -> Async<U> { return Async<U> { callback in self.run { value in transform(value).run(callback) } } }}फंक्शन कंपोज़िशन: पाइपलाइन बनाना
फंक्शन कंपोज़िशन कई फ़ंक्शनों को क्रमिक रूप से लागू करके एक नया फ़ंक्शन बनाना है। स्विफ्ट में, इसे ऑपरेटर या क्लोजर के माध्यम से कार्यान्वित किया जा सकता है।
// कंपोज़िशन ऑपरेटरprecedencegroup CompositionPrecedence { associativity: left higherThan: FunctionArrowPrecedence}
infix operator >>> : CompositionPrecedence
func >>>(_ f: @escaping (A) -> B, _ g: @escaping (B) -> C) -> (A) -> C { return { x in g(f(x)) }}
// उदाहरण: मान्यकरण और स्वरूपणlet trimWhitespace: (String) -> String = { $0.trimmingCharacters(in: .whitespaces) }let capitalize: (String) -> String = { $0.capitalized }let addExclamation: (String) -> String = { $0 + "!" }
let processString = trimWhitespace >>> capitalize >>> addExclamationprint(processString(" hello world ")) // "Hello World!"कंपोज़िशन विशेष रूप से डेटा ट्रांसफ़ॉर्मेशन की श्रृंखलाओं के साथ काम करते समय उपयोगी है, जैसे नेटवर्क प्रतिक्रियाओं को संसाधित करते समय।
// त्रुटि प्रबंधन के साथ उन्नत कंपोज़िशनtypealias ResultFunction = (T) -> Result<U, Error>
func compose(_ f: @escaping ResultFunction<T, U>, _ g: @escaping ResultFunction<U, V>) -> ResultFunction<T, V> { return { input