البرمجة الوظيفية في Swift: المستوى المتقدم

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

البرمجة الوظيفية في Swift: المستوى المتقدم



تم تصميم Swift في الأصل كلغة متعددة النماذج، مما يجعله منصة مثالية لتطبيق تقنيات البرمجة الوظيفية المتقدمة. في هذه المقالة، سنستعرض مفاهيم تتجاوز الإغلاقات الأساسية و map/filter/reduce — سنتحدث عن functors و monads و composition functions و currying و memoization. ستساعدك هذه الأدوات على كتابة كود أكثر قابلية للتنبؤ والاختبار والتعبير لتطبيقات iOS و macOS.



Functors و Monads: العمل مع السياقات



Functor هو نوع يقوم بتنفيذ دالة map، مما يسمح بتطبيق تحويل على القيمة داخل السياق. في Swift، الأمثلة الكلاسيكية للـ functors هي Optional و Array.



// Functor Optionallet value: Int? = 42let result = value.map { $0 * 2 } // Optional(84)

// Functor Arraylet numbers = [1, 2, 3]let doubled = numbers.map { $0 * 2 } // [2, 4, 6]


Monad هو functor مع عملية إضافية flatMap (أو >>= في Haskell). تسمح هذه العملية بـ "فك" السياقات المتداخلة. يدعم Swift الـ monads ضمنيًا من خلال بروتوكول Monad، لكن الأنواع الرئيسية (Optional و Result و Async) تنفذ هذا المنطق.



// Monad Optional: سلسلة عمليات مع احتمال nilfunc 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)

// Monad Result لمعالجة الأخطاءenum 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)


تطبيق متقدم: إنشاء نوع monad مخصص للعمل مع العمليات غير المتزامنة.



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) }        }    }}


Composition Functions: بناء pipeline



Composition functions هي إنشاء دالة جديدة من خلال تطبيق عدة دوال بشكل متسلسل. في Swift، يمكن تحقيق ذلك عبر عامل تشغيل أو إغلاقات.



// عامل تشغيل التركيب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

المدونات

توصيات الكتب