English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
التعاقب هو جزء مهم من Erlang. دعونا أولاً نرى كيف يمكننا تحقيق برنامج factorial بسيط من خلال التنفيذ.
-module(helloworld). -export([fac/1, start/0]). fac(N) when N == 0 -> 1; fac(N) when N > 0 -> N * fac(N - 1). start() -> X = fac(4), io:fwrite("~w",[X]).
يجب الانتباه إلى النقاط التالية بشأن البرنامج المذكور أعلاه:
سنبدأ بتعريف دالة تسمى fac(N).
يمكننا تعريف دالة تعاقبية fac(N) من خلال استدعاء fac(N).
مخرجات البرنامج أعلاه هي:
24
في هذا الفصل، سنستعرض بدقة أنواع التعاقب المختلفة وكيفية استخدامها في Erlang.
يمكن رؤية طريقة أكثر عملية للتعاقب من خلال مثال بسيط لتحديد طول القائمة. يمكن للقائمة أن تحتوي على عدة قيم، مثل [1,2,3,4]. دعونا نستخدم التعاقب لرؤية كيفية الحصول على طول القائمة.
-module(helloworld). -export([len/1, start/0]). len([]) -> 0; len([_|T]) -> 1 + len(T). start() -> X = [1,2,3,4], Y = len(X), io:fwrite("~w",[Y]).
يجب الانتباه إلى النقاط التالية بشأن البرنامج المذكور أعلاه:
إذا كان القائمة فارغة، فإن الدالة الأولى len([]) تستخدم للحالة الخاصة.
[H|T] نمط للتوافق مع قائمة تحتوي على عنصر أو أكثر، مثل قائمة طول 1 تُعرف بـ [X|[]], وقائمة طول 2 تُعرف بـ [X|[Y|[]]].
لاحظ أن العنصر الثاني هو القائمة نفسها. هذا يعني أننا نحتاج إلى حساب الأول فقط، يمكن للدالة أن تنطلق على العنصر الثاني. يتم حساب طول القائمة المحددة لكل قيمة كـ 1.
سيكون خروج البرنامج أعلاه
4
للتفهم كيفية عمل التكرار التكامل، دعونا نرى كيف تعمل الآلة في الجملة التالية من القسم السابق.
النحو
len([]) -> 0; len([_|T]) -> 1 + len(T).
الإجابة على 1 + len (Rest) تحتاج إلى إيجاد إجابة len (Rest). ثم تحتاج دالة len (Rest) نفسها إلى إيجاد نتيجة لطلب دالة أخرى. سيتراكم الجزء المضافة حتى يتم العثور على الأخير، ثم يمكن حساب النتيجة النهائية.
التكرار التكامل يهدف إلى القضاء على هذه العمليات المتراكمة عن طريق تقليلها عند حدوث العمليات.
لتحقيق ذلك، نحتاج إلى الحفاظ على متغير مؤقت إضافي كمعامل في الدالة. المتغير المؤقت المذكور في الماضي يُسمى أحياناً ملاكمة، ويستخدم كحفظ مكان التخزين للنتائج لتحديد نمو الطلبات.
دعونا نرى مثالاً على التكرار التكامل
-module(helloworld). -export([tail_len/1,tail_len/2,start/0]). tail_len(L) -> tail_len(L,0). tail_len([], Acc) -> Acc; tail_len([_|T], Acc) -> tail_len(T,Acc+1). start() -> X = [1,2,3,4], Y = tail_len(X), io:fwrite("~w",[Y]).
يكون خروج البرنامج أعلاه
4
دعونا نرى مثالاً على التكرار. دعونا نكتب دالة ستأخذ عددًا كاملًا كأول معامل، ثم أي عنصر آخر كمعامل ثاني. ثم ستقوم بإنشاء قائمة تحتوي على نسخ من الترمة المحددة من قبل العدد.
دعونا نرى مثل هذا المثال-
-module(helloworld). -export([duplicate/2,start/0]). duplicate(0,_) -> []; duplicate(N,Term) when N > 0 -> io:fwrite("~w,~n",[Term]), [Term|duplicate(N-1,Term)]. start() -> duplicate(5,1).
سيكون الإخراج للبرنامج أعلاه هو -
1, 1, 1, 1, 1,
في Erlang يمكن استخدام التكرار بشكل غير محدود. دعونا نلقي نظرة سريعة على كيفية استخدام التكرار لقلب عناصر القائمة. يمكن استخدام البرنامج التالي لتنفيذ هذه العملية.
-module(helloworld). -export([tail_reverse/2,start/0]). tail_reverse(L) -> tail_reverse(L,[]). tail_reverse([],Acc) -> Acc; tail_reverse([H|T],Acc) -> tail_reverse(T, [H|Acc]). start() -> X = [1,2,3,4], Y = tail_reverse(X), io:fwrite("~w",[Y]).
سيكون الإخراج للبرنامج أعلاه هو -
[4,3,2,1]
يجب الانتباه إلى النقاط التالية بشأن البرنامج المذكور أعلاه:
نستخدم مرة أخرى مفهوم المتغيرات المؤقتة لتحديد كل عنصر في القائمة في متغير يُدعى Acc.
ثم يتم استدعاء tail_reverse مرة أخرى، ولكن هذه المرة، نضمن أن يتم وضع العنصر الأخير في القائمة الجديدة أولاً.
ثم يتم استدعاء tail_reverse لكل عنصر في القائمة.