نوع «اتحادیهی تفکیکشده» نمایندهی تعداد ثابتی از حالتهای نامدار است. هر مقدار از یک اتحادیهی تفکیکشده دقیقاً با یکی از حالتهای نامدار متناظر است.
اتحادیهی تفکیکشده با کلیدواژهی type تعریف میشود و حالتهایش با کاراکترهای خط عمودی (|) از هم جدا میشوند:
type Season =
| Spring
| Summer
| Autumn
| Winter
هر حالت از یک اتحادیهی تفکیکشده میتواند بهصورت اختیاری دادهای همراه داشته باشد و حالتهای مختلف میتوانند نوعهای متفاوتی از داده داشته باشند. اگر هیچکدام از حالتها دادهی همراه نداشته باشند، اتحادیهی تفکیکشده شبیه چیزی است که در زبانهای دیگر معمولاً «برشماری» (یا «enum») نامیده میشود.
type Number =
| Integer of int
| Float of float
| Invalid
ساختن مقدار برای یک حالت خاص با ارجاع به اسم آن انجام میشود (مثلاً Success). از آنجا که اسمهای حالت فقط توابع سازندهاند، میتوان دادهی همراه را مانند یک آرگومان معمولی تابع ارسال کرد. اگر اتحادیهی تفکیکشدهی دیگری حالتی با همین اسم تعریف کرده باشد، باید از اسم کامل آن استفاده کنید (مثلاً Result.Success).
let byName = Integer 2
let byFullName = Number.Invalid
اتحادیههای تفکیکشده «برابری ساختاری» دارند؛ یعنی دو مقداری که برای یک حالت یکسان و با دادهی (اختیاری) یکسان ساخته شدهاند، همارزند.
هرچند میتوان برای کار با اتحادیههای تفکیکشده از عبارتهای if/elif/else استفاده کرد، روش توصیهشده برای کار با آنها «تطبیق الگو» با استفاده از «الگوی شناسه» است:
let describe number =
match number with
| Integer i -> sprintf "Integer: %d" i
| Float d -> sprintf "Float: %f" d
| Invalid -> "Invalid"
در این تمرین، روز ولنتاین است و شما و شریک زندگیتان قصد دارید با هم کار قشنگی انجام دهید. شریک زندگیتان ایدههای زیادی دارد و حالا از شما میخواهد به ایدهها امتیاز دهید تا فعالیتی را که میخواهید انجام دهید پیدا کنید.
ایدههای زیر توسط شریک زندگیتان پیشنهاد شده است:
شش وظیفه برای کمک به انتخاب فعالیت روز ولنتاین دارید.
برای هر ایدهای که شریک زندگیتان پیشنهاد میکند، با یکی از سه گزینه پاسخ میدهید: بله، خیر یا شاید.
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