۱۶ - ۲فانکتور چیه؟

فانکتور راهی برای اعمال ِ یه تابع از روی (یا از اطرافِ) یه ساختار ایه که نمی‌خوایم تغییر کنه. یعنی می‌خوایم تابع رو به مقداری که داخلِ یه ساختار هست اعمال کنیم و کاری به کارِ اون ساختار نداشته باشیم. به همین خاطر هم هست که اکثراً معرفیِ فانکتور رو با fmap کردن روی لیست‌ها شروع می‌کنن، کاری که ما هم در فصلِ لیست‌ها انجام دادیم. تابع به تک‌تکِ مقادیرِ داخلِ لیست اعمال میشه و ساختار ِ لیست سرجاش باقی می‌مونه. مفهومِ "تغییر نکردنِ ساختار" رو برای لیست میشه اینطور گفت که طولِ لیست بعد از نگاشت ِ یه تابع روی اون لیست، ثابت می‌مونه و تغییری نمی‌کنه. نه المانی اضافه میشه، نه المانی حذف میشه، فقط المان‌ها تغییر می‌کنن. تایپکلاسِ ‏‎Functor‎‏ این الگو رو تعمیم میده تا بشه از ایده‌ی کلی نه فقط برای لیست، بلکه برای ساختارهای متنوع دیگه‌ای هم استفاده کرد.

در هسکل، ‏‎Functor‎‏ هم مثلِ ‏‎Monoid‎‏ از طریقِ یه تایپکلاس پیاده‌سازی شده. از راه‌های دیگه هم میشه فانکتور رو پیاده‌سازی کرد، ولی این از همه راحت‌تر و کاربردی‌تره. تعریفِ تایپکلاسِ ‏‎Functor‎‏ اینطوره:

class Functor f where
  fmap :: (a -> b) -> f a -> f b

حالا تشریح‌ش کنیم ببینیم چی به چیه:

 class Functor f where
-- [1] [2]    [3]  [4]
   fmap :: (a -> b) -> f a -> f b
-- [5]       [6]       [7]     [8]

۱.

تعریفِ یه تایپکلاس، با کلیدواژه ِ ‏‎class‎‏ شروع میشه.

۲.

‏‎Functor‎‏ اسمِ تایپکلاسی‌ه که داریم تعریف می‌کنیم.

۳.

معمولاً تایپکلاس‌ها در هسکل به یه تایپ اشاره می‌کنن. اینجا هم مثل متغیرهای تایپ در تایپ سیگنچر ها، حروف به خودیِ خود مفهومی ندارن. یه جور رسم‌ه که از حرفِ ‏‎f‎‏ برای اشاره به تایپ‌هایی که ساختار ِ فانکتوری دارن استفاده بشه. در طول تعریفِ تایپکلاس، این ‏‎f‎‏ باید ‏‎f‎‏ بمونه.

۴.

کلیدواژه ِ ‏‎where‎‏ تعریفِ اسمِ تایپکلاس، و تایپ‌های مربوطه‌ش رو پایان میده. بعد از ‏‎where‎‏، عملیات‌هایی که تایپکلاس ارائه میده لیست میشن.

۵.

تعریفِ یک عملیات به اسمِ ‏‎fmap‎‏ رو شروع می‌کنیم.

۶.

آرگومانِ ‏‎(a -> b)‎‏ هر تابعِ هسکل با این تایپ رو نشون میده( که حتی ممکنه ‏‎(a -> a)‎‏ هم باشه).

۷.

آرگومانِ ‏‎f a‎‏ یک فانکتور ِ ‏‎f‎‏ هست که یک آرگومانِ تایپیِ ‏‎a‎‏ می‌گیره. یعنی ‏‎f‎‏ تایپی‌ه که یک نمونه از تایپکلاسِ ‏‎Functor‎‏ داره.

۸.

تایپِ مقدارِ خروجی ‏‎f b‎‏ هست. این همون ‏‎f‎‏ایه که تو ‏‎f a‎‏ هم بود، فقط آرگومانِ تایپیِ ‏‎b‎‏ ممکنه به یه تایپِ متفاوت اشاره کنه، ولی نه لزوماً.

قبل از اینکه جزئیات و نحوه‌ی کارِ این تایپکلاس رو بگیم، اول چندتا مثال از ‏‎fmap‎‏ در عمل ببینیم تا یه حس کلی ازش پیدا کنیم.