۶ - ۱۴تمرینهای فصل
تستی
۱.
کلاس 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 = 1
b)
حالا با این تایپ سیگنچر امتحان کنین:
i :: a
اول به جواب خودتون برسین و بعد تستش کنین. وقتی درست یا غلط بودنِ جوابتون رو درک کردین، با GHCi امتحان کنین ببینین بدون اینکه تایپی تعریف کنین، چه تایپی برای بیانیه نتیجه میگیره. مثلاً برای این مثال، بنویسین:
Prelude> let i = 1
Prelude> :t i
--جواب رو عمداً نیاوردیم.
۲.
a)
f :: Float
f = 1.0
b)
f :: Num a => a
۳.
a)
f :: Float
f = 1.0
b)
f :: Fractional a => a
۴.
راهنمایی: :info RealFrac
رو در REPL تایپ کنین.
a)
f :: Float
f = 1.0
b)
f :: RealFrac a => a
۵.
a)
freud :: a -> a
freud x = x
b)
freud :: Ord a => a -> a
۶.
a)
freud' :: a -> a
freud' x = x
b)
freud' :: Int -> Int
۷.
a)
myX = 1 :: Int
sigmund :: Int -> Int
sigmund x = myX
b)
sigmund :: a -> a
۸.
a)
myX = 1 :: Int
sigmund' :: Int -> Int
sigmund' x = myX
b)
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 = ???