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

Currying

التطبيق الجزئي

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

ما المقصود بـ currying؟

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

object Main {
  def add(a: Int)(b: Int): Int = a + b
  def main(args: Array[String]): Unit = {
    println(add(3)(4))
  }
}

قوائم المعلمات المتعددة

يحتوي الأسلوب ذي صيغة currying على عدة قوائم معلمات: def f(a: Int)(b: Int). ويُستدعى بتوفير كل قائمة بالتتابع: f(1)(2).

object Main {
  def combine(prefix: String)(value: Int): String = s"$prefix$value"
  def main(args: Array[String]): Unit = {
    println(combine("id-")(42))
  }
}

التطبيق الجزئي

يمكنكم تطبيق بعض قوائم الوسيطات فقط، والحصول على دالة تنتظر بقية الوسيطات. ويُسمى ذلك التطبيق الجزئي.

object Main {
  def add(a: Int)(b: Int): Int = a + b
  def main(args: Array[String]): Unit = {
    val addFive = add(5) _
    println(addFive(10))
    println(addFive(20))
  }
}

تخصيص دالة عامة

يتيح التطبيق الجزئي إنشاء دوال متخصصة انطلاقًا من دالة عامة، مما يقلل التكرار.

object Main {
  def power(exp: Int)(base: Int): Int = math.pow(base, exp).toInt
  def main(args: Array[String]): Unit = {
    val square = power(2) _
    val cube = power(3) _
    println(square(5))
    println(cube(2))
  }
}

تطبيق currying على دالة عادية

تحتوي قيمة الدالة العادية على أسلوب .curried يحولها إلى صيغة currying.

object Main {
  def main(args: Array[String]): Unit = {
    val add = (a: Int, b: Int) => a + b
    val curriedAdd = add.curried
    println(curriedAdd(3)(4))
  }
}

إلغاء currying

تعكس الأداة المساعدة Function.uncurried العملية، فتحوّل الدالة ذات صيغة currying إلى دالة ذات قائمة معلمات واحدة.

object Main {
  def main(args: Array[String]): Unit = {
    val curried: Int => Int => Int = a => b => a + b
    val normal = Function.uncurried(curried)
    println(normal(3, 4))
  }
}

فائدة currying

يتيح currying إعادة الاستخدام: ثبّتوا الوسيطات الأولى مرة واحدة، ثم استدعوا الناتج مرات متعددة باستخدام وسيطات متبقية مختلفة. كما يساعد المترجم على استنتاج الأنواع في القوائم اللاحقة.

object Main {
  def discount(rate: Double)(price: Double): Double = price * (1 - rate)
  def main(args: Array[String]): Unit = {
    val blackFriday = discount(0.3) _
    println(blackFriday(100))
    println(blackFriday(250))
  }
}

استنتاج النوع في القائمة الأخيرة

من الأسباب العملية لاستخدام قوائم المعلمات المتعددة أن المترجم يستطيع استنتاج أنواع معلمات lambda من القوائم السابقة، لذلك يمكنكم حذفها.

object Main {
  def fold[A](xs: List[A])(init: A)(op: (A, A) => A): A =
    xs.foldLeft(init)(op)
  def main(args: Array[String]): Unit = {
    val total = fold(List(1, 2, 3))(0)((a, b) => a + b)
    println(total)
  }
}

استخدام currying مع ثلاث قوائم

يمكنكم استخدام أي عدد تريدونه من قوائم المعلمات. ويوفّر كل استدعاء قائمةً واحدة ويُعيد دالةً للقائمة التالية.

object Main {
  def make(a: Int)(b: Int)(c: Int): Int = a + b + c
  def main(args: Array[String]): Unit = {
    println(make(1)(2)(3))
    val step = make(10) _
    println(step(20)(30))
  }
}

بناء أدوات تحقق قابلة للتهيئة

من الاستخدامات الواقعية الشائعة: تطبيق currying على قاعدة تحقق، وتثبيت الحد، ثم إعادة استخدام الدالة الشرطية الناتجة عبر مجموعة بيانات.

object Main {
  def atLeast(min: Int)(value: Int): Boolean = value >= min
  def main(args: Array[String]): Unit = {
    val adult = atLeast(18) _
    println(List(15, 21, 18, 12).map(adult))
  }
}

الفرق بين currying والتطبيق الجزئي

Currying هو التحويل البنيوي إلى دوال تأخذ وسيطة واحدة. أما التطبيق الجزئي فهو تزويد الدالة ببعض الوسيطات الآن والباقي لاحقًا. وتجعل الدوال ذات صيغة currying التطبيق الجزئي طبيعيًا.

object Main {
  def greet(greeting: String)(name: String): String = s"$greeting, $name!"
  def main(args: Array[String]): Unit = {
    val sayHi = greet("Hi") _
    println(sayHi("Ann"))
    println(sayHi("Bob"))
  }
}

اختبار سريع

كيف تعرّفون أسلوبًا بصيغة currying في Scala؟

مراجعة

لقد تعلّمتم currying والتطبيق الجزئي:

  • تستخدم الأساليب ذات صيغة currying قوائم معلمات متعددة: f(a)(b)
  • طبّقوا الدالة جزئيًا باستخدام f(x) _ للحصول على دالة جديدة
  • يحوّل .curried وFunction.uncurried بين الصيغتين
  • يساعد ذلك في إعادة الاستخدام والتخصيص واستنتاج الأنواع

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

هل درس «Currying» مجاني؟

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

ماذا ستتعلم في «Currying»؟

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

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

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

كم من الوقت يستغرق درس «Currying»؟

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

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

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

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

  1. الدوال كقيم
  2. Currying
  3. التركيب
  4. Closures
← العودة إلى Scala for Backend Engineering & Functional Programming