۴ - ۵مقایسهی مقادیر
تا اینجا بیشترِ عملیاتی که با اعداد داشتیم محاسبات بودن. اعداد رو میشه برای تساوی، بزرگتر بودن، یا کوچکتر بودن هم مقایسه کرد:
Prelude> let x = 5
Prelude> x == 5
True
Prelude> x == 6
False
Prelude> x < 7
True
Prelude> x > 3
True
Prelude> x /= 5
Falseدقت کنید که در خط اول با یک علامت تساوی مقداری برای x تعریف کردیم. پس میدونیم که تا آخر این جلسه ِوREPL همهی x ها مقدارِ ۵ دارن. چونکه از علامت تساوی برای تعاریف استفاده شده، برای آیا مساوی هست با باید از دو تا علامت تساوی استفاده کنیم. علامتِ =/ معادلِ مساوی نیست با، و بقیهی علائم هم حتماً میشناسین.
با توجه به نتیجهی بیانیهها، GHCi دو مقدارِ True یا False رو برمیگردوند. قبلاً دیدیم که True و Falseودادهسازهای نوعدادهو ِBool بودن. اگه تایپِ هر کدوم از این عملگرها رو از GHCiواستعلام کنین، میبینین که تایپِ جوابشون Bool ِه:
Prelude> :t (==)
(==) :: Eq a => a -> a -> Bool
Prelude> :t (<)
(<) :: Ord a => a -> a -> Boolبه محدودیتهای تایپکلاسی دقت کنین. Eq تایپکلاسیه که شامل هر چیزِ قابل مقایسه برای تساوی میشه؛ Ord هم یه تایپکلاسه که شامل هر چیزِ ترتیبدار میشه. و هیچ کدومِشون هم محدود به اعداد نیستن. اعداد رو میشه مقایسه و مرتب کرد، ولی حروف هم همینطور، پس این محدودیتِ تایپکلاس خیلی هم محدودکننده نیست. هر مقداری که بشه براش تساوی یا ترتیب تعریف کرد، میتونه ورودی به این توابعِ تساوی و مقایسه باشه. مابقی اطلاعات تایپ به ما میگه که تابع یکی از این مقادیر رو میگیره، با یه همنوعِ خودش مقایسه میکنه، و یه Bool برمیگردونه. همونطور که قبلاً هم دیدیم، مقادیرِ Bool،وTrue یا False اند.
یه کم با مقادیر دیگه بازی کنیم:
Prelude> 'a' == 'a'
True
Prelude> 'a' == 'b'
False
Prelude> 'a' < 'b'
True
Prelude> 'a' > 'b'
False
Prelude> 'a' == 'A'
False
Prelude> "Julie" == "Chris"
Falseمیدونیم که حروف الفبا ترتیب دارن، با این حال معمولاً a رو "کوچکتر" از b نمیگیم. به جاش میگیم که در الفبا a قبل از b میاد. در مثال آخر دیدیم که با نوشته هم همین قاعده کار میکنه. GHCi به درستی تساوی اون دو نوشته رو نقض کرده.
حالا با REPL ببینید 'a' بزرگتره یا 'A'.
بعد مثالهای زیر رو بررسی کنید. میتونین دلیل جوابهای REPL رو تشخیص بدین؟
Prelude> "Julie" > "Chris"
True
Prelude> "Chris" > "Julie"
Falseخوبه که هسکل هم واقعیت رو میگه! "Julie" از "Chris" بزرگتره چون 'J' > 'C'، اگه دو لغتِ "Back" و "Brack" رو مقایسه میکردیم، اون موقع حرف اول رد میشد (چون 'B' == 'B') و با مقایسهی حرفهای دوم، "Brack" بزرگتر میشد ('r' > 'a' با ترتیب الفبایی). دقت کنید که این مقایسه بر مبنای نمونه ِتایپکلاسِ Ord برای هر دو تایپِ لیست و Char انجام شد. فقط لیستهایی رو میشه با هم مقایسه کرد که المانهاشون هم نمونهو ِOrd داشته باشن. لیستهای زیر قابل مقایسهاند، چون Char و Integer هر دو یکی یه نمونه از Ord دارن:
Prelude> ['a', 'b'] > ['b', 'a']
False
Prelude> 1 > 2
False
Prelude> [1, 2] > [2, 1]
Falseنوعداده ای که نمونهو ِOrd نداره با این توابع کار نمیکنه:
Prelude> data Mood = G | B deriving Show
Prelude> [G, B]
[G, B]
Prelude> [G, B] > [B, G]
<interactive>:28:14:
No instance for (Ord Mood) arising
from a use of ‘>’
In the expression: [G, B] > [B, G]
In an equation for ‘it’:
it = [G, B] > [B, G]معنی پیغامِ (No instance for (Ord Mood اینه که نمونه ِOrd وجود نداره، پس نمیدونه چطور مقادیر رو مرتب کنه.
چیز دیگهای که با این توابع کار نمیکنه:
Prelude> "Julie" == 8
<interactive>:38:12:
No instance for (Num [Char]) arising
from the literal ‘8’
In the second argument of ‘(==)’,
namely ‘8’
In the expression: "Julie" == 8
In an equation for ‘it’:
it = "Julie" == 8بالاتر گفتیم که توابعِ مقایسه، چندریختی اند و متعاقباً میتونن با تایپهای متنوعی کار کنند. چیز دیگهای که گفتیم این بود که طبق اطلاعات تایپِشون که دیدیم، فقط تایپهای یکسان رو قبول میکردند. به محض اینکه یک مقدارِ String (در سطح جملهای)، مثل "Julie" به چنین توابعی میدیم، تایپِ تابع تعیین میشه، و آرگومانِ دوم هم باید از همون تایپ باشه. پیغام خطای بالا میگه که تایپِ مقدارِ لیترالو ِ۸ با تایپِ مقدار اول منطبق نیست، که بر خلافِ انتظارِ این تابعه.