یک «نوع دادهی جبری» (ADT) تعداد ثابتی از حالتهای نامدار را نمایش میدهد. هر مقدار از یک نوع دادهی جبری دقیقاً با یکی از حالتهای نامدار متناظر است.
یک نوع دادهی جبری با کلیدواژهی data تعریف میشود و حالتهای آن با کاراکتر خط عمودی (|) از هم جدا میشوند.
اگر هیچیک از حالتها دادهی وابستهای نداشته باشند، این نوع دادهی جبری شبیه چیزی است که در زبانهای دیگر معمولاً به آن «برشماری» (یا «enum») میگویند.
data Season
= Spring
| Summer
| Autumn
| Winter
هر حالت از یک نوع دادهی جبری میتواند بهصورت اختیاری دادهی وابستهای داشته باشد و حالتهای مختلف میتوانند انواع متفاوتی از داده داشته باشند. وقتی یک حالت دادهی وابسته دارد، به یک «سازنده» نیاز است.
data Number
= NInt Int --'NInt' is the constructor for an Int Number.
| NFloat Float --'NFloat' is the constructor for an Float Number.
| Invalid --'Invalid' does not have data associated to it.
ساخت یک مقدار برای یک حالت مشخص با اشاره به اسم آن انجام میشود (مثلاً NInt 22).
چون اسم حالتها صرفاً توابع سازنده هستند، دادهی وابسته را میتوان مانند یک آرگومان معمولی تابع پاس داد.
نوعهای دادهی جبری «برابری ساختاری» دارند؛ یعنی دو مقدار برای یک حالت و با دادهی یکسان (اختیاری) معادلاند.
هرچند میتوان با عبارات if/else با نوعهای دادهی جبری کار کرد، روش توصیهشده برای کار با آنها استفاده از «تطبیق الگو» به کمک دستور case است:
add1 :: Number -> String
add1 number =
case number of
NInt i -> show (i + 1)
NFloat f -> show (f + 1.0)
Invalid -> error "Invalid input"
در این تمرین، روز ولنتاین است و دارید برنامهریزی میکنید که با شریک زندگیتان چه کار کنید. شریک زندگیتان ایدههای زیادی دارد و از شما میخواهد این ایدهها را ارزیابی کنید تا بهترین فعالیت پیدا شود.
ایدههای زیر را شریک زندگیتان پیشنهاد داده است:
شش کار پیش رو دارید که در انتخاب فعالیت روز ولنتاین به شما کمک میکنند.
برای هر ایدهای که شریک زندگیتان پیشنهاد میدهد، با یکی از سه گزینه پاسخ میدهید: yes، no یا maybe.
نوع دادهی جبری Approval را تعریف کنید تا این گزینهها را با سه حالت زیر نمایش دهد: Yes، No یا Maybe.
شریک زندگیتان دو رستوران ممکن را انتخاب کرده است: یکی با آشپزی کرهای و دیگری با آشپزی ترکی.
نوع دادهی جبری Cuisine را تعریف کنید تا این رستورانها را با دو حالت زیر نمایش دهد: Korean یا Turkish.
فیلمهای بیشماری برای انتخاب وجود دارد، بنابراین شریک زندگیتان برای محدودتر کردن انتخابها، ژانر مورد علاقهی خود را هم فهرست میکند.
نوع دادهی جبری Genre را تعریف کنید تا حالتهای ژانر زیر را نمایش دهد: Crime، Horror، Romance یا Thriller.
همانطور که گفته شد، شریک زندگیتان پنج فعالیت ممکن را پیشنهاد داده است: انجام یک بازی رومیزی، استراحت کردن، تماشای فیلم، رفتن به رستوران و قدم زدن.
نوع دادهی جبری Activity را تعریف کنید تا این انواع فعالیت را نمایش دهد:
BoardGame: هیچ دادهی همراهی ندارد.Chill: هیچ دادهی همراهی ندارد.Movie: Genre خود را به عنوان دادهی همراه دارد.Restaurant: Cuisine خود را به عنوان دادهی همراه دارد.Walk: یک Int به عنوان دادهی همراه دارد که شمار کیلومترهای پیادهروی را نشان میدهد.در پایان، آمادهاید که ایدههای شریک زندگیتان را ارزیابی کنید. احساس شما دربارهی ایدهی شریک زندگیتان این است:
تابعی به اسم rateActivity پیادهسازی کنید که یک مقدار Activity میگیرد و بر اساس احساسهای بالا Approval را برمیگرداند.
برای مثال:
rateActivity (Restaurant Turkish)
-- -> Maybe