0Pricing
Scala for Backend Engineering & Functional Programming · درس

الدوال عالية الرتبة والتطبيق الجزئي

استكشف مفاهيم وظيفية متقدمة مثل الدوال عالية الرتبة والتطبيق الجزئي لإنشاء تعليمات برمجية مرنة وقابلة لإعادة الاستخدام

الدوال عالية الرتبة والتطبيق الجزئي درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 2 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Scala for Backend Engineering & Functional Programming، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Scala for Backend Engineering & Functional Programming 3 دروس في المجموع.

إطلاق العنان للدوال عالية الرتبة

مرحبًا بكم في الدرس الثاني! تُعدّ الدوال في البرمجة الوظيفية قوية للغاية. فهي ليست مخصّصة لحساب القيم فحسب، بل يمكن أيضًا التعامل معها مثل أي بيانات أخرى.

وهذا يعني أنه يمكن تمرير الدوال كوسائط إلى دوال أخرى، أو حتى إرجاعها كقيم ناتجة عنها. وعندما تفعل الدالة ذلك، تُسمّى دالة عالية الرتبة (HOF).

  • تأخذ الدوال عالية الرتبة دالة واحدة أو أكثر كوسائط.
  • تُرجع الدوال عالية الرتبة دالةً كقيمة ناتجة.
  • أو تفعل الأمرين معًا!

تطبيق عملي للدوال عالية الرتبة: `map`

تُعدّ map إحدى أكثر الدوال عالية الرتبة شيوعًا في Scala. فهي تحوّل كل عنصر في مجموعة من خلال تطبيق دالة معيّنة عليه، ثم تُرجع مجموعة جديدة.

جرّبوا تشغيل هذا المثال البسيط:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3)
    val doubledNumbers = numbers.map(x => x * 2)
    println(s"Original: $numbers")
    println(s"Doubled: $doubledNumbers")
  }
}

تطبيق عملي للدوال عالية الرتبة: `filter`

تُعدّ filter دالة عالية الرتبة أخرى مفيدة. فهي تختار من المجموعة العناصر التي تستوفي شرطًا معيّنًا (أي دالة تُرجع قيمة منطقية)، ثم تنشئ مجموعة جديدة.

إليكم طريقة استخدام filter للعثور على الأعداد الزوجية:

object Main {
  def main(args: Array[String]): Unit = {
    val allNumbers = List(1, 2, 3, 4, 5, 6)
    val evenNumbers = allNumbers.filter(x => x % 2 == 0)
    println(s"All: $allNumbers")
    println(s"Even: $evenNumbers")
  }
}

تعريف دالة عالية الرتبة خاصة بكم

لستم مقيّدين بالدوال عالية الرتبة المضمّنة! يمكنكم تعريف دوالكم الخاصة التي تقبل دوال أخرى كمعاملات. وصيغة نوع الدالة هي (InputType => ReturnType).

يعرّف هذا المثال دالة باسم applyOperation تأخذ قيمة من النوع Int ودالة أخرى باسم op (تأخذ قيمة من النوع Int وتُرجع قيمة من النوع Int).

object Main {
  // A HOF that applies an operation to a number
  def applyOperation(x: Int, op: Int => Int): Int = {
    op(x)
  }

  def main(args: Array[String]): Unit = {
    val result = applyOperation(10, _ * 3) // Pass an anonymous function
    println(s"Result of 10 * 3: $result")

    val anotherResult = applyOperation(7, _ + 5)
    println(s"Result of 7 + 5: $anotherResult")
  }
}

الدوال المجهولة والصيغة المختصرة

عند تمرير الدوال إلى الدوال عالية الرتبة، غالبًا ما تستخدمون الدوال المجهولة (وتُسمّى أيضًا lambdas). توفّر Scala طرقًا موجزة لكتابتها.

  • x => x * 2: دالة مجهولة كاملة.
  • _ * 2: صيغة مختصرة لدالة مجهولة ذات معامل واحد.

كلتا الصيغتين شائعتان، وتساعدان على جعل الشيفرة أقصر وأسهل قراءة.

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(10, 20, 30)

    // Using full anonymous function syntax
    val dividedByTwo = numbers.map(x => x / 2)
    println(s"Divided by two: $dividedByTwo")

    // Using shorthand `_` syntax
    val plusOne = numbers.map(_ + 1)
    println(s"Plus one: $plusOne")
  }
}

مقدمة إلى Currying

إن Currying تقنية تحوّل دالةً تأخذ عدة وسائط إلى سلسلة من الدوال، تأخذ كل واحدة منها وسيطًا واحدًا.

سُمّيت هذه التقنية نسبةً إلى عالم المنطق Haskell Curry. وفي Scala، تُحوَّل الدوال ذات قوائم المعاملات المتعددة تلقائيًا إلى دوال باستخدام Currying.

بدلًا من f(arg1, arg2)، تكتبون f(arg1)(arg2).

مثال على Currying: قوائم معاملات متعددة

لنرَ Currying قيد التطبيق. لاحظوا أن add تأخذ وسائطها في قائمتَي معاملات منفصلتين.

يتيح لكم ذلك التطبيق الجزئي للدالة، وإنشاء دوال جديدة من خلال تثبيت بعض الوسائط.

object Main {
  // A curried function with two parameter lists
  def add(a: Int)(b: Int): Int = {
    a + b
  }

  def main(args: Array[String]): Unit = {
    // Call the function normally
    println(s"5 + 3 = ${add(5)(3)}")

    // Partially apply the first argument
    val addFive = add(5)_ // `_` tells Scala to treat it as a partially applied function
    println(s"5 + 10 = ${addFive(10)}")
    println(s"5 + 20 = ${addFive(20)}")
  }
}

فوائد Currying

لماذا نستخدم Currying؟ يوفّر عدة مزايا في البرمجة الوظيفية:

  • التطبيق الجزئي: إنشاء نسخ متخصصة من دالة عبر تثبيت بعض الوسائط، مما يحسّن إعادة استخدام الشيفرة.
  • تركيب الدوال: غالبًا ما يكون تركيب الدوال التي تستخدم Currying مع دوال أخرى أسهل.
  • استنتاج الأنواع: قد يساعد أحيانًا في استنتاج الأنواع في Scala، لا سيما عند التعامل مع الأنواع العامة المعقّدة.

استخدام Currying لإنشاء مسجّلات مخصّصة

تخيّلوا أنكم تريدون إنشاء دوال تسجيل مختلفة لمستويات مختلفة (مثل INFO وERROR)، مع استخدام المنطق الأساسي نفسه. تُعدّ Currying مثالية لهذا الغرض!

يمكنكم تعريف دالة عامة باسم log، ثم تطبيقها جزئيًا لإنشاء مسجّلات مخصّصة.

object Main {
  def log(level: String)(message: String): Unit = {
    println(s"[$level] $message")
  }

  def main(args: Array[String]): Unit = {
    // Create specialized loggers using partial application
    val infoLogger = log("INFO")_
    val errorLogger = log("ERROR")_

    infoLogger("User logged in successfully.")
    errorLogger("Failed to connect to database!")
  }
}

تحقّق سريع: الدوال عالية الرتبة وCurrying

تأمّلوا مقطع شيفرة Scala التالي:

def calculate(x: Int)(y: Int, op: (Int, Int) => Int): Int = {
  op(x, y)
}

val add = (a: Int, b: Int) => a + b
val multiply = (a: Int, b: Int) => a * b

val result1 = calculate(10)(5, add)
val result2 = calculate(2)(3, multiply)

ما قيمتا result1 وresult2؟

مراجعة: الدوال عالية الرتبة وCurrying

أحسنتم! تعرّفتم إلى مفهومين قويين في البرمجة الوظيفية:

  • الدوال عالية الرتبة (HOFs): دوال يمكنها أخذ دوال أخرى كوسائط أو إرجاعها كقيم ناتجة. وهي تتيح كتابة شيفرة مرنة وقابلة لإعادة الاستخدام، مثل map وfilter.
  • Currying: تقنية تحوّل دالة ذات وسائط متعددة إلى سلسلة من الدوال، تأخذ كل واحدة منها وسيطًا واحدًا. وهي ممتازة للتطبيق الجزئي وإنشاء دوال متخصصة.

تُعدّ هذه المفاهيم أساسية لكتابة شيفرة Scala واضحة ومعبّرة وقابلة للتقسيم إلى وحدات!

الأسئلة الشائعة

هل درس «الدوال عالية الرتبة والتطبيق الجزئي» مجاني؟

نعم — نص درس «الدوال عالية الرتبة والتطبيق الجزئي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 3 دروس في المجموع.

ماذا ستتعلم في «الدوال عالية الرتبة والتطبيق الجزئي»؟

استكشف مفاهيم وظيفية متقدمة مثل الدوال عالية الرتبة والتطبيق الجزئي لإنشاء تعليمات برمجية مرنة وقابلة لإعادة الاستخدام تتمرن على Scala for Backend Engineering & Functional Programming مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Scala for Backend Engineering & Functional Programming؟

لا تُشترط خبرة سابقة. Scala for Backend Engineering & Functional Programming على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 3.

كم من الوقت يستغرق درس «الدوال عالية الرتبة والتطبيق الجزئي»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Scala for Backend Engineering & Functional Programming هذا؟

نعم. كل درس في Scala for Backend Engineering & Functional Programming يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الدوال كقيم من الدرجة الأولى
  2. الدوال عالية الرتبة والتطبيق الجزئي
  3. عدم القابلية للتغيير والآثار الجانبية
← العودة إلى Scala for Backend Engineering & Functional Programming