پرش به محتویات

تطبیق الگو

در بخش قبل، یاد گرفتیم که چگونه نوع داده سفارشی با کلمه کلیدی type ایجاد کنیم. مثال ما User در یک اتاق چت بود:

type User
  = Regular String Int
  | Visitor String

کاربران عادی دارای نام و سن، در حالی که بازدیدکنندگان دارای نام هستند. اکنون نوع داده سفارشی را داریم، اما چگونه از آن استفاده کنیم؟

عبارت case

فرض کنید می‌خواهیم یک تابع toName داشته باشیم که تصمیم بگیرد چه نامی برای هر User نمایش دهد. نیاز به استفاده از یک عبارت case داریم:

toName : User -> String
toName user =
  case user of
    Regular name age ->
      name

    Visitor name ->
      name

-- toName (Regular "Thomas" 44) == "Thomas"
-- toName (Visitor "kate95")    == "kate95"

عبارت case به ما اجازه می‌دهد بر اساس مشاهده هر حالت، شاخه‌بندی جداگانه‌ای برای آن داشته باشیم. بنابراین هر کاربری را که ببینیم، همیشه می‌دانیم چگونه نام آن را نمایش دهیم.

اگر سعی کنیم آرگومان‌های نامعتبر مانند toName (Visitar "kate95") یا toName Anonymous را امتحان کنیم، کامپایلر بلافاصله به ما اطلاع می‌دهد. این بدان معناست که بسیاری از اشتباهات ساده می‌توانند در عرض چند ثانیه اصلاح شوند، بجای اینکه بدست کاربران برسند و زمان بیشتری را تلف کنند.

کاراکتر جایگزین

تابع toName که تازه تعریف کردیم عالی کار می‌کند، اما توجه می‌کنید که مقدار age در پیاده‌سازی آن استفاده نشده است؟ زمانی که برخی از داده‌های مرتبط استفاده نمی‌شوند، معمول است که بجای دادن نام به آن، از یک کاراکتر "_" استفاده کنیم:

toName : User -> String
toName user =
  case user of
    Regular name _ ->
      name

    Visitor name ->
      name

کاراکتر _ وجود داده را تایید می‌کند، اما بطور صریح می‌گوید از آن استفاده نمی‌شود.


یادداشت مترجم

با استفاده از نوع داده سفارشی و تطبیق الگو، می‌توانید پیچیده‌ترین حالت‌های ممکن در یک وبسایت، وب اپلیکیشن یا بازی را مدل‌سازی کنید. این الگو با نام Make Impossible States Impossible شناخته می‌شود. برای کسب اطلاعات بیشتر، به منابع زیر مراجعه کنید: