۱۰ - ۱۱تعاریف
۱.
فولد یا fold نوعی تابعِ سطح بالا هست که با داشتن یه تابع برای انباشته کردن نتایج، و یه ساختار دادهی بازگشتی، مقدارِ انباشته شده رو برمیگردونه. معمولاً در کنارِ اون تابع (که قابلیت ترکیبِ تایپهای مقادیر داخلِ ساختار داده، و مقدارِ انباشته شده رو داره) یه "مقدار اولیه" یا start value هم تأمین میشه. برای حالت عمومیتر از "تخریب و حذفِ ساختار،" به کاتامورفیسم رجوع کنید.
۲.
کاتامورفیسم یا catamorphism تعمیمی از فولد برای انواعِ نوعدادههاست. با فولد میشه یه لیست رو تخریب کرد و یه تایپِ دلخواه ازش بدست آورد، اما کاتامورفیسم امکان تخریبِ ساختارِ هر نوعداده ای رو فراهم میکنه. تابعِ bool :: a -> a -> Bool -> a
در Data.Bool
یک مثال از کاتامورفیسم برای نوعداده ِ ساده و غیرمجموعهای هست. تابعِ maybe :: b -> (a -> b) -> Maybe a -> b
هم کاتامورفیسم برای Maybe
ِه. ببینید متوجه الگویی میشین:
data Bool = False | True
bool :: a -> a -> Bool -> a
data Maybe a = Nothing | Just a
maybe :: a -> (a -> b) -> Maybe a -> b
data Either a b = Left a | Right b
either :: (a -> c)
-> (a -> b)
-> Either a b
-> c
۳.
فراخوان نهایی یا tail call آخرین نتیجهی یه تابعه. یه مثال از فراخوان نهایی در توابعِ هسکل:
f x y z = h (subFunction x y z)
where subFunction x y z = g x y z
-- اینجا، فراخوانِ نهایی میشه:
-- h (subFunction x y z)
-- .h یا دقیقتر بگیم، خودِ
۴.
خوداتکاییِ نهایی یا tail recursion به تابعی گفته میشه که فراخوانِ نهایی ِش خودِ تابعه، و متمایز با توابعیه که در فراخوان نهایی شون توابعِ دیگهای رو صدا میزنن.
f x y z = h (subFunction x y z)
where subFunction x y z = g x y z
این خوداتکاییِ نهایی نداره، h
رو صدا میزنه، نه خودش رو.
f x y z = h (f (x – 1) y z)
هنوز خوداتکایی نهایی نداره. f
دوباره صدا زده شده، اما نه در فراخوانِ نهایی؛ f
یکی از آرگومانهای نهایی در فراخوان نهایی ِ h
ِه:
f x y z = f (x – 1) y z
حالا خوداتکاییِ نهایی داره. f
بدون هیچ دخالتی مستقیماً خودش رو صدا میزنه.
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
خوداتکایی نهایی نداره. قبل از ادامهی لیست، اختیار رو به تابع ترکیبکننده ِ f
میدیم. فراخوانهای بازگشتی در foldr
بین foldr
و f
در تناوباند.
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs
خوداتکایی نهایی داره. foldl
به طورِ بازگشتی خودش رو صدا میزنه. اون تابع فولدینگ، فقط یکی از آرگومانهای فولد ِ بازگشتی ِه.