۱۹ - ۲کلاسِ Foldable

در مستنداتِ Hackage، تایپکلاس ‏‎Foldable‎‏ اینطور توصیف شده: "کلاسِ ساختارهای داده‌ای که میشه به یک مقدارِ خلاصه فولد بشن." عملیات‌های فولد ای که قبلاً دیدیم به خوبی با این توصیف جور درمیان، اما این تایپکلاس شامل عملیات‌های زیادی ِه. تعریفِ کاملِ این تایپکلاس رو خورده‌خورده میگیم. تعریف‌ش در کتابخونه اینطور شروع میشه:

class Foldable t where
  {-# MINIMAL foldMap | foldr #-}

کلیدواژه ِ ‏‎MINIMAL‎‏ در این تایپکلاس میگه برای تعریفِ کاملِ این تایپکلاس، فقط کافیه یکی از متود‌های ‏‎foldMap‎‏ یا ‏‎foldr‎‏ تعریف بشن. دلیل این "یا" اینه که هم ‏‎foldMap‎‏ و هم ‏‎foldr‎‏ رو میشه برمبنای اون یکی تعریف کرد، بقیه‌ی عملیات‌های این تایپکلاس رو هم میشه با هر کدوم از این دوتا تعریف کرد. در نتیجه اگه فقط یکی از اینها تعریف بشن، یه نمونه‌ای از ‏‎Foldable‎‏ دارین که کار می‌کنه. بعضی متود‌های تایپکلاس تعریفِ پیش‌فرض دارن که در صورتِ نیاز میشه با تعاریفِ جدید باطل‌شون کرد. چنین کاری معمولاً وقتی لازم میشه که می‌خواین یه راه به‌صرفه‌تر برای انجامِ کاری مختصِ نوع‌داده‌ِتون پیاده‌سازی کنین.

اگه اطلاعات تایپکلاس رو در GHCi استعلام کنین، در اولین خط کایند سیگنچر ِ ‏‎t‎‏ رو می‌بینین:

class Foldable (t :: * -> *) where

گونه‌بالا بودنِ اون ‏‎t‎‏ نباید عجیب باشه: لیست‌ها تایپ‌های گونه‌بالا اند. به همون دلیلی که برای ‏‎Functor‎‏ هم تایپِ گونه‌بالا لازم داشتیم، اینجا هم ‏‎t‎‏ باید گونه‌بالا باشه، و می‌بینیم که تأثیرِ مشابهی هم داره. تایپ‌هایی که بیشتر از یک آرگومانِ تایپی می‌گیرن، مثلِ ‏‎Either‎‏ و توپل، لزوماً اولین آرگومانِ تایپی‌شون باید جزئی از ساختار‌ِشون بشه.

لطفاً دقت داشته باشین که برای همه‌ی مثال‌های این فصل باید از GHC 7.10 یا جدیدتر استفاده کنین. با اینکه ‏‎Prelude‎‏ تا GHC 7.10 شاملِ خیلی تغییراتِ مرتبط با تایپکلاسِ ‏‎Foldable‎‏ شده، ولی همه‌ی ‏‎Foldable‎‏ تو ‏‎Prelude‎‏ نیست. برای پیشروی با مثال‌های این فصل، ممکنه لازم بشه ‏‎Data.Foldable‎‏ و ‏‎Data.Monoid‎‏ (برای چندتا از ‏‎newtype‎‏ های ‏‎Monoid‎‏) رو وارد کنین.