0Pricing
TypeScript Academy · درس

Functors وMappers العامة

اكتبوا دوال map عامة لأي حاوية

Functors وMappers العامة درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

Functor عام

نستخدم الترميز الآن لغايته: إنشاء map عامة تعمل مع أي حاوية مسجّلة. وتعلن واجهة Functor، المعلّمة بواسطة URI، عن أسلوب واحد.

interface Functor<F extends URIS> {
  readonly URI: F;
  map<A, B>(fa: Kind<F, A>, f: (a: A) => B): Kind<F, B>;
}

نسخة Array

تنفّذ النسخة map لـ URI واحد. وتستخدم نسخة Array أسلوب المصفوفة المضمّن لإجراء التحويل. ويُحلّ Kind<"Array", A> إلى A[].

const arrayFunctor: Functor<"Array"> = {
  URI: "Array",
  map: (fa, f) => fa.map(f)
};

استخدام نسخة Array

يحوّل استدعاء map على نسخة Array كل عنصر مع الحفاظ على نوع حاوية المصفوفة.

const doubled = arrayFunctor.map([1, 2, 3], n => n * 2);
// doubled: number[] -> [2, 4, 6]

نوع Option

عرّفوا Option على أنه قيمة أو null، ثم سجّلوه. وتطبّق map الخاصة به الدالة فقط عند وجود قيمة، وإلا فتنقل null كما هو.

interface URItoKind<A> { Option: A | null }
type Option<A> = A | null;

نسخة Option

تحافظ نسخة Option على حاوية الخيار: فتُطبّق الدالة على القيمة، بينما تبقى null هي null.

const optionFunctor: Functor<"Option"> = {
  URI: "Option",
  map: (fa, f) => (fa === null ? null : f(fa))
};

استخدام نسخة Option

يعمل شكل map نفسه الآن على حاوية مختلفة تمامًا. فتتحول القيم الموجودة، بينما تُترك القيم الغائبة دون تغيير.

const a = optionFunctor.map(5, n => n + 1);    // 6
const b = optionFunctor.map(null, n => n + 1); // null

تجريد واحد وحاويات متعددة

هنا تظهر الفائدة. تشترك arrayFunctor وoptionFunctor في واجهة Functor نفسها. وتعمل الشيفرة المكتوبة اعتمادًا على Functor<F> مع كليهما من دون تغيير.

function bumpAll<F extends URIS>(
  F: Functor<F>,
  fa: Kind<F, number>
): Kind<F, number> {
  return F.map(fa, n => n + 1);
}

استدعاء الدالة العامة

لا تعرف bumpAll الحاوية التي تتلقاها ولا تهتم بها. مرّروا النسخة والبيانات، وستحافظ النتيجة على نوع الحاوية.

const arr = bumpAll(arrayFunctor, [1, 2]); // number[] -> [2, 3]
const opt = bumpAll(optionFunctor, 9);     // number | null -> 10

قوانين Functor

يلتزم Functor الصحيح بقانونين: لا يغيّر تطبيق دالة الهوية شيئًا، ويعادل تطبيق دالتين بالتتابع تطبيق تركيبهما. وتستوفي كل من نسختي Array وOption المذكورتين أعلاه هذين القانونين.

// map(fa, x => x) === fa
// map(map(fa, f), g) === map(fa, x => g(f(x)))

إضافة نسخ أخرى

بما أن التجريد مفتوح، يمكن وصل حاويات جديدة بتسجيل URI وتوفير نسخة. فالشجرة ونتيجة العملية والمهمة، كل منها يصبح قابلًا لتطبيق map باستخدام الشيفرة العامة نفسها.

// Register URI, implement Functor<"Tree">,
// and bumpAll works on trees too - no edits to bumpAll

لماذا يهم ذلك

تُعد Functors العامة مدخلًا إلى التجريدات الوظيفية في TypeScript: مثل applicatives وmonads وtraversals. كل منها واجهة تعمل فوق Kind<F, A>، مع نسخ لكل حاوية. وأصبحتم الآن تفهمون الآلية التي تجعل fp-ts وEffect ممكنتين.

interface Monad<F extends URIS> extends Functor<F> {
  of<A>(a: A): Kind<F, A>;
  chain<A, B>(fa: Kind<F, A>, f: (a: A) => Kind<F, B>): Kind<F, B>;
}

تحقق سريع

اختبروا مدى فهمكم لـ Functors العامة.

مراجعة

كتبتم map عامة تعمل مع الحاويات.

  • تعلن Functor<F> عن map تعمل فوق Kind<F, A>.
  • تنفّذ نسختا Array وOption ذلك لـ URI الخاص بكل منهما.
  • تعمل شيفرة عامة مثل bumpAll مع أي حاوية مسجّلة.
  • تحافظ قوانين Functor على اتساق النسخ، وتُبنى التجريدات الأثرى فوقها.

المقرر 24 التالي: بناء محللات آمنة من ناحية الأنواع.

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

هل درس «Functors وMappers العامة» مجاني؟

نعم — نص درس «Functors وMappers العامة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

ماذا ستتعلم في «Functors وMappers العامة»؟

اكتبوا دوال map عامة لأي حاوية تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟

لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «Functors وMappers العامة»؟

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

هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟

نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

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

  1. مشكلة HKT في TypeScript
  2. تعريف مُنشئات الأنواع
  3. نمط HKT خفيف الوزن
  4. Functors وMappers العامة
← العودة إلى TypeScript Academy