۱۰ - ۳الگوهای بازگشتی
بار دیگه تابعِ sum رو ببینیم:
Prelude> sum [1, 5, 10]
16قبلاً هم دیده بودیم که یه لیست میگیره، المانهاش رو با هم جمع میکنه و یه مقدارِ مجرد برمیگردونه. یه شباهتهایی با تابعِ map داره، مثل این میمونه که تابعِ (+) روی یه لیست نگاشت و با تکتکِ عملگرهای cons جایگزین بشه، و در نهایت یک مقدارِ مجرد برگردونه. ولی با map میتونستیم مثلاً (+1) رو به تکتکِ سلولهای cons ِ لیست اعمال کنیم و نهایتاً هم یه لیستِ کامل از جوابها میگرفتیم. میشه گفت تابعِ sum تلفیقی از نگاشت ِ یه تابع به یک لیست، و کاهش (یا حذف) لیست از خروجیه. قبلتر در کتاب، این تابع رو به صورتِ بازگشتی اینطور نوشتیم:
sum :: [Integer] -> Integer
sum [] = 0
sum (x:xs) = x + sum xsتابعِ length رو هم به خاطر بیاریم:
length :: [a] -> Integer
length [] = 0
length (x:xs) = 1 + length xsشباهتشون رو میبینین؟ اگه product و concat هم مقایسه کنیم:
product :: [Integer] -> Integer
product [] = 1
product (x:xs) = x * product xs
concat :: [[a]] -> Integer
concat [] = []
concat (x:xs) = x ++ concat xsفرمان پایه برای همه این توابع، مقدار همانی ِ تابعِ اصلیشونه. پس به ترتیب برای sum، length، product، و concat مقدارِ همانی معادلِ صفر، صفر، ۱، و [] هست. جمعِ هر عددی با صفر، خود اون عدد رو نتیجه میده، مثلِ ۱ = ۰ + ۱، ولی برای ضرب، عددِ ۱ مقدارِ همانی ِه: ۲ = ۲ × ۱. برای الحاق ِ لیستها، مقدارِ همانی یه لیست خالی میشه، مثل: [1,2,3] ++ [] == [1,2,3].
چیز دیگهای که بین این تابعها مشترکه، یک تابعِ اصلیِه که با شرکتپذیری از راست، به صورتِ بازگشتی اعمال میشه. سَر ِ لیست محاسبه و کنار گذاشته میشه، تابع میره راست و سَر ِ بعدی رو حساب میکنه؛ همینطور تا آخر.