۶ - ۱۴تمرینهای فصل
تستی
۱.
کلاس Eq
a)
شامل همهی تایپها در هسکل میشه
b)
با تایپکلاس Ord یکسانه
c)
بررسی تساوی رو ممکن میکنه
d)
فقط شامل تایپهای عددی میشه
۲.
تایپکلاس Ord
a)
امکان مقایسهی همهی مقادیر با هم رو میده
b)
یه زیرکلاس از Eq ِه
c)
یه سوپرکلاس برای Eq ِه
d)
هیچ نمونهای برای Bool نداره
۳.
فرض کنیم تایپکلاس Ord یه عملگر ِ > داره. تایپش چیه؟
a)
Ord a => a -> a -> Bool
b)
Ord a => Int -> Bool
c)
Ord a => a -> Char
d)
Ord a => Char -> [Char]
۴.
در بیانیهی x = divMod 16 12
a)
x تایپش Integer ِه
b)
مقدار x رو نمیشه تشخیص داد
c)
تایپِ x توپل ِه
d)
x برابرِ 12 / 16 میشه
۵.
تایپکلاس Integral شامل
a)
اعداد Int و Integer
b)
اعداد Integral، Real، و Fractional
c)
گربهی شرودینگر
d)
فقط اعداد مثبت
تایپچک میشه؟
تو این بخش از تمرینها، دنبالِ خطاهای تایپ و تایپکلاس گشتن رو تمرین میکنین.
برای مثال printIt کار نمیکنه چون تابعهایی مثلِ x هیچ نمونهای از Show ندارن – تایپکلاسی که اجازهی تبدیلِ چیزها به نوشته رو میده (معمولاً برای چاپ):
x :: Int -> Int
x blah = blah + 20
printIt :: IO ()
printIt = putStrLn (show x)این خطاییه که بعد از بارگذاری میگیرین:
No instance for (Show (Int -> Int)) arising
from a use of ‘show’
In the first argument of ‘putStrLn’,
namely ‘(show x)’
In the expression: putStrLn (show x)
In an equation for ‘printIt’:
printIt = putStrLn (show x)پیغام میگه نمونه ِ Show برای تایپ Int -> Int پیدا نکرده، که با عقل جور در میاد. در هسکل به طور پیشفرض هیچ چیز با نوعساز ِ تابع (->) نمیتونه نمونه ِ Show داشته باشه.
کدهای زیر رو بررسی کنین و بگین تایپچک میشن یا نه، بعد هم با GHC تست کنین. اگه تایپچک نمیشه، سعی کنین پیغام خطا رو با حدسِ خودتون از ایرادِ کُد مقایسه کنین. اگر هم تونستین کد رو درست کنین.
۱.
کد زیر تایپچک میشه؟ اگه نه، چرا؟
data Person = Person Bool
printPerson :: Person -> IO ()
printPerson person = putStrLn (show person)۲.
کد زیر تایپچک میشه؟ اگه نه، چرا؟
data Mood = Blah
| Woot deriving Show
settleDown x = if x == Woot
then Blah
else x۳.
اگه کاری کنین settleDown تایپچک بشه، اون موقع:
a)
چه مقادیری برای ورودیِ تابع قابل قبولاند؟
b)
چی میشه اگه settleDown 9 رو اجرا کنین؟ چرا؟
c)
اگه Blah > Woot رو اجرا کنین چی میشه؟ چرا؟
۴.
کد زیر تایپچک میشه؟ اگه نه، چرا؟
type Subject = String
type Verb = String
type Object = String
data Sentence =
Sentence Subject Verb Object
deriving (Eq, Show)
s1 = Sentence "dogs" "drool"
s2 = Sentence "Julie" "loves" "dogs"با یه تعریفِ نوعداده، چی کار میشه کرد؟
با تعاریف نوعدادههای زیر:
data Rocks =
Rocks String deriving (Eq, Show)
ata Yeah =
Yeah Bool deriving (Eq, Show)
ata Papu =
Papu Rocks Yeah
deriving (Eq, Show)کدوم کدهای زیر تایپچک میشن؟ اونهایی که نمیشن مشکلشون چیه؟
۱.
phew = Papu "chases" True۲.
truth = Papu (Rocks "chomskydoz")
(Yeah True)۳.
equalityForAll :: Papu -> Papu -> Bool
equalityForAll p p' = p == p'۴.
comparePapus :: Papu -> Papu -> Bool
comparePapus p p' = p > p'تایپها رو جور کنین
یه بیانیه با دو تا تایپ بهتون میدیم، و شما باید بگین که آیا میشه تایپِ دوم رو با تایپِ اول عوض کرد یا نه. برای تست، میتونین همهی بیانیهها رو با تایپِ اولشون تو یه فایل بنویسین و بعد تایپها رو با تایپِ دوم عوض کنین، بارگذاری کنین و ببینین کار میکنه یا نه. حدس نزنین، همهی جوابهاتون رو چک کنین!
۱.
برای تعریفِ زیر:
a)
i :: Num a => a
i = 1b)
حالا با این تایپ سیگنچر امتحان کنین:
i :: aاول به جواب خودتون برسین و بعد تستش کنین. وقتی درست یا غلط بودنِ جوابتون رو درک کردین، با GHCi امتحان کنین ببینین بدون اینکه تایپی تعریف کنین، چه تایپی برای بیانیه نتیجه میگیره. مثلاً برای این مثال، بنویسین:
Prelude> let i = 1
Prelude> :t i
--جواب رو عمداً نیاوردیم. ۲.
a)
f :: Float
f = 1.0b)
f :: Num a => a۳.
a)
f :: Float
f = 1.0b)
f :: Fractional a => a۴.
راهنمایی: :info RealFrac رو در REPL تایپ کنین.
a)
f :: Float
f = 1.0b)
f :: RealFrac a => a۵.
a)
freud :: a -> a
freud x = xb)
freud :: Ord a => a -> a۶.
a)
freud' :: a -> a
freud' x = xb)
freud' :: Int -> Int۷.
a)
myX = 1 :: Int
sigmund :: Int -> Int
sigmund x = myXb)
sigmund :: a -> a۸.
a)
myX = 1 :: Int
sigmund' :: Int -> Int
sigmund' x = myXb)
sigmund' :: Num a => a -> a۹.
باید sort رو از Data.List وارد کنین.
a)
jung :: Ord a => [a] -> a
jung xs = head (sort xs)b)
jung :: [Int] -> Int۱۰.
a)
young :: [Char] -> Char
young xs = head (sort xs)b)
young :: Ord a => [a] -> a۱۱.
a)
mySort :: [Char] -> [Char]
mySort = sort
signifier :: [Char] -> Char
signifier xs = head (mySort xs)b)
signifier :: Ord a => [a] -> aتایپ-وان-دو ۲
راندِ دوم! مثل قبل – باید جاهای خالی رو طوری پر کنید که با تایپها جور بشن. هدفِ این تمرینها اینه که شما تعریفِ یه بیانیه رو از روی تایپش پیدا کنین. احتمالاً چندتا چیز از Prelude لازم بشه.
۱.
chk :: Eq b => (a -> b) -> a -> b -> Bool
chk = ???۲.
-- با یکی از عملیات حساب، مقادیرِ
-- رو ترکیب کنین Integer و b
arith :: Num b
=> (a -> b)
-> Integer
-> a
-> b
arith = ???