۳ - ۸تمرین‌های فصل

خوندنِ گرامر

۱.

سلامت گرامریِ هر کدوم از کُدهای زیر رو تعیین کنین. بعد از اینکه به نتیجه رسیدین، کدها رو توی REPL تست کنین. هر چندتا رو که تونستین تصحیح کنین.

a)

concat [[1, 2, 3], [4, 5, 6]]

b)

++ [1, 2, 3] [4, 5, 6]

c)

(++) "hello" " world"

d)

["hello" ++ "world]

e)

4 !! "hello"

f)

(!!) "hello" 4

g)

take "4 lovely"

h)

take 3 "awesome"

۲.

اینجا دو دسته داریم. دسته‌ی اول چند خط کد اند، و دسته‌ی دوم جواب اونهاست. کد رو بخونین و جوابش رو از دسته‌ی دوم پیدا کنین. حتماً در REPL هم امتحان کنین.

a)

concat [[1 * 6], [2 * 6], [3 * 6]]

b)

"rain" ++ drop 2 "elbow"

c)

10 * head [1, 2, 3]

d)

(take 3 "Julie") ++ (tail "yes")

e)

concat [tail [1, 2, 3],
        tail [4, 5, 6],
        tail [7, 8, 9]]

جوابِ کدهای بالا رو این زیر نوشتیم، ولی ترتیب‌شون درست نیست.

a)

"Jules"

b)

[2,3,5,6,8,9]

c)

"rainbow"

d)

[6,12,18]

e)

10

ساخت توابع

۱.

بر مبنای توصیفی که از توابع داده شده، به همراه ورودی و خروجی موردِ نظرشون، تعریف تابع رو بنویسید. اینکار رو مستقیماً در REPL انجام بدین.

به عنوان مثال:

-- اگه تابع‌تون رو به این مقدار
-- اعمال کنید:
"Hello World"
-- باید چنین جوابی برگردونه:
"ello World"

این جوابِ مناسبی‌ه:

Prelude> drop 1 "Hello World"
"ello World"

حالا بیانیه‌هایی بنویسین که تبدیلاتِ زیر رو انجام بدن. توابعی که تو این فصل دیدین کفایت می‌کنن و هیچ کدوم نکته‌ی گمراه‌کننده‌ای ندارن.

a)

-- داریم
"Curry is awesome"
-- جواب بده
"Curry is awesome!"

b)

-- داریم
"Curry is awesome!"
-- جواب بده
"y"

c)

-- داریم
"Curry is awesome!"
-- جواب بده
"awesome!"

۲.

حالا جواب‌هاتون رو به صورت توابعِ جامع که آرگومان‌های نوشتاری می‌گیرن، تو یه فایل بنویسین. از یه متغیر به عنوان آرگومان تابعِ اسم‌دارِتون استفاده کنین. اگه مطمئن نیستین چطور این توابع رو بنویسین، می‌تونین تمرینِ ‏‎waxOff‎‏ از فصلِ قبل و یا ماژول ِ ‏‎TopOrLocal‎‏ از این فصل رو دوره کنین.

۳.

یه تابع با تایپِ ‏‎String -> Char‎‏ بنویسین که حرف سومِ ورودی‌ش رو برمی‌گردونه. یادتون باشه که یه اسم به تابع بدین، و به یه متغیر هم اعمال‌ِش کنین (نه به یه ‏‎String‎‏ ِ معین) تا بشه به ‏‎String‎‏ های مختلف اِعمال‌ِش کرد. مقداری از کد رو اینجا نوشتیم (اگه دوست داشتین اسم تابع رو تغییر بدین. حتماً تایپ سیگنچرِ تابع رو بنویسین؛ تعریف تابع رو هم بعد از علامت مساوی بیارین):

thirdLetter ::
thirdLetter x =

-- اگه اون تابع رو به این مقدار
-- اعمال کنید:
"Curry is awesome"
-- باید این جواب رو برگردونه:
'r'

فقط دقت کنین که مثلِ اکثر زبان‌های برنامه‌نویسی، اندیس‌ها در هسکل از صفر شروع میشن، پس صفرُمین اندیس ِ یه نوشته، حرف اولش میشه. و متعاقباً، سومین اندیس میشه حرف چهارم.

۴.

حالا تابع‌تون رو طوری تغییر بدین که همیشه با یه نوشته ِ به‌خصوص کار کنه، و اندیس ِ حرف مورد نظر رو به عنوان ورودی بگیره (می‌تونین از ‏‎Curry is awesome!‎‏ برای نوشته ِ داخلِ تابع استفاده کنین، یا اگه دوست داشتین یه نوشته ِ دیگه بنویسین).

letterIndex  :: Int -> Char
letterIndex x =

۵.

با استفاده از توابعِ ‏‎take‎‏ و ‏‎drop‎‏ که تو این فصل دیدیم، سعی کنین یه تابع به اسم ‏‎rvrs‎‏ بنویسین (خلاصه‌ای از لغت reverse به معنای معکوس. ‏‎Prelude‎‏ خودِش یه تابع به اسم ‏‎reverse‎‏ داره و اگه شما هم همون اسم رو به تابع‌تون بدین، پیغام خطا می‌گیرین) که نوشته‌ی Curry is awesome رو به نوشته‌ی awesome is Curry تبدیل می‌کنه. کُد خیلی جالبی نیست، اما چیزهایی که تا الان یاد گرفتیم برای نوشتنِ این تابع کاملاً کفایت می‌کنن. اول تابع رو تو یه فایل تعریف کنین. قرار نیست که این تابع لغات همه‌ی جملات رو معکوس کنه، فقط با ‏‎drop‎‏ و ‏‎take‎‏ لغاتِ همون یک جمله رو جابجا کنین.

۶.

حالا سعی کنیم فایل‌مون رو به یه ماژول گسترش بدیم. این کار اجازه میده بعداً توابع بیشتری بهش اضافه کنیم، همچنین می‌تونیم توابعِ این ماژول رو به ماژول‌های دیگه صادر کنیم تا اونها هم به این توابع دسترسی پیدا کنن. راههای متفاوتی برای این کار هست، ولی برای راحتی؛ این الگوی ساده رو در زیر آوردیم:

module Reverse where

rvrs :: String -> String
rvrs x =

main :: IO ()
main = print ()

داخل پرانتز جلوی ‏‎print‎‏، تابع ‏‎rvrs‎‏ رو با آرگومانی که میخواین بهش اعمال شه (در این مورد Curry is awesome) بنویسین. حالا اون تابع ‏‎rvrs‎‏ به همراه آرگومانِ‌ش، مجموعاً آرگومان تابع ‏‎print‎‏ شدن. دقت کنید که حتماً داخل پرانتز بنویسین، تا نتیجه‌ی ‏‎rvrs‎‏ چاپ بشه.

البته همونطور که گفتیم، میشه از ‏‎$‎‏ هم برای کاهش پرانتزها استفاده کرد. این روش هم امتحان کنین.