التركيب
andThen وcompose
التركيب درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Scala for Backend Engineering & Functional Programming، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.
تركيب الدوال
يعني تركيب الدوال إنشاء دالة جديدة بربط دالتين موجودتين، بحيث يصبح ناتج إحداهما مُدخلًا للأخرى. توفّر Scala الدالتين andThen وcompose لهذا الغرض.
object Main {
def main(args: Array[String]): Unit = {
val addOne = (x: Int) => x + 1
val double = (x: Int) => x * 2
val both = addOne andThen double
println(both(5))
}
}andThen: من اليسار إلى اليمين
ينفّذ f andThen g الدالة f أولًا ثم g. وتتوافق القراءة من اليسار إلى اليمين مع ترتيب التنفيذ، وهو ما يجده كثيرون بديهيًا.
(f andThen g)(x) == g(f(x))
object Main {
def main(args: Array[String]): Unit = {
val addOne = (x: Int) => x + 1
val triple = (x: Int) => x * 3
val pipeline = addOne andThen triple
println(pipeline(4)) // (4 + 1) * 3
}
}compose: من اليمين إلى اليسار
ينفّذ f compose g الدالة g أولًا ثم f، وفق الترتيب الرياضي f(g(x)).
(f compose g)(x) == f(g(x))
object Main {
def main(args: Array[String]): Unit = {
val addOne = (x: Int) => x + 1
val triple = (x: Int) => x * 3
val pipeline = addOne compose triple
println(pipeline(4)) // (4 * 3) + 1
}
}andThen مقابل compose
الدالتان صورتان متعاكستان:
f andThen g=g compose ff compose g=g andThen f
اختاروا الصيغة التي تبدو قراءتها أكثر طبيعية في حالتكم.
object Main {
def main(args: Array[String]): Unit = {
val f = (x: Int) => x + 10
val g = (x: Int) => x * 2
println((f andThen g)(3))
println((g compose f)(3))
}
}ربط عدة دوال
يمكنكم ربط عدة دوال باستخدام تكرار andThen لإنشاء مسار أطول يتدفق من الأعلى إلى الأسفل.
object Main {
def main(args: Array[String]): Unit = {
val clean = (s: String) => s.trim
val lower = (s: String) => s.toLowerCase
val bang = (s: String) => s + "!"
val process = clean andThen lower andThen bang
println(process(" HELLO "))
}
}يغيّر التركيب الأنواع
يجب أن تكون أنواع الدوال المركبة متوافقة: إذ يجب أن يطابق نوع خرج الدالة الأولى نوع دخل الدالة الثانية. ويمكن للمسار أن يغيّر الأنواع أثناء تقدمه.
object Main {
def main(args: Array[String]): Unit = {
val length = (s: String) => s.length
val isLong = (n: Int) => n > 5
val check = length andThen isLong
println(check("scala"))
println(check("functional"))
}
}دالة الهوية
تعيد identity القيمة المُدخلة دون تغيير. وهي العنصر المحايد للتركيب: f andThen identity == f. وتفيد كقيمة افتراضية في عمليات الطيّ والعبارات الشرطية.
object Main {
def main(args: Array[String]): Unit = {
val f = (x: Int) => x * 2
val same = f andThen identity[Int]
println(same(7))
}
}التركيب باستخدام reduce
بما أن الدوال قيم، يمكنكم تخزين عدة دوال في قائمة وتركيبها كلها باستخدام reduce مع andThen.
object Main {
def main(args: Array[String]): Unit = {
val steps: List[Int => Int] = List(_ + 1, _ * 2, _ - 3)
val pipeline = steps.reduce(_ andThen _)
println(pipeline(5)) // ((5+1)*2)-3
}
}إنشاء مسارات قابلة لإعادة الاستخدام
يشجّع التركيب على إنشاء دوال صغيرة مخصّصة لغرض واحد، ثم تجميعها لتكوين سلوك أكبر؛ وهذه فكرة أساسية في البرمجة الوظيفية.
object Main {
def main(args: Array[String]): Unit = {
val sanitize = (s: String) => s.trim.toLowerCase
val capitalize = (s: String) => s.capitalize
val format = sanitize andThen capitalize
println(format(" aLiCe "))
}
}التركيب مع map
الدالة المركّبة هي دالة عادية، لذا يمكنكم تمريرها مباشرةً إلى map لتطبيق المسار بأكمله على عناصر مجموعة.
object Main {
def main(args: Array[String]): Unit = {
val transform = ((x: Int) => x + 1) andThen ((x: Int) => x * x)
println(List(1, 2, 3).map(transform))
}
}قراءة ترتيب التركيب بعناية
من الأخطاء الشائعة الخلط بين andThen وcompose. تذكّروا دائمًا: andThen = هذا أولًا، ثم ذاك؛ وcompose = الترتيب العكسي.
object Main {
def main(args: Array[String]): Unit = {
val inc = (x: Int) => x + 1
val sqr = (x: Int) => x * x
println((inc andThen sqr)(2)) // (2+1)^2 = 9
println((inc compose sqr)(2)) // (2^2)+1 = 5
}
}تحقّق سريع
بالنظر إلى f وg، ما القيمة التي تحسبها (f andThen g)(x)؟
مراجعة
لقد تعلّمتم تركيب الدوال:
f andThen g→g(f(x))(من اليسار إلى اليمين)f compose g→f(g(x))(من اليمين إلى اليسار)- هما صورتان معكوسِتان لبعضهما
identityهو العنصر المحايد- ركّبوا قوائم الدوال باستخدام
reduce(_ andThen _)
الأسئلة الشائعة
هل درس «التركيب» مجاني؟
نعم — نص درس «التركيب» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 4 دروس في المجموع.
ماذا ستتعلم في «التركيب»؟
andThen وcompose تتمرن على Scala for Backend Engineering & Functional Programming مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Scala for Backend Engineering & Functional Programming؟
لا تُشترط خبرة سابقة. Scala for Backend Engineering & Functional Programming على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «التركيب»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Scala for Backend Engineering & Functional Programming هذا؟
نعم. كل درس في Scala for Backend Engineering & Functional Programming يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الدوال كقيم
- Currying
- التركيب
- Closures