۳ - ۶الحاق و گستره
از پرانتز استفاده میکنیم تا تابعِ ++
رو به صورت پیشوندی (و نه میانوندی) استفاده کنیم:
-- print3flipped.hs
module Print3Flipped where
myGreeting :: String
myGreeting = (++) "hello" " world!"
hello :: String
hello = "hello"
world :: String
world = "world!"
main :: IO ()
main = do
putStrLn myGreeting
putStrLn secondGreeting
where secondGreeting =
(++) hello ((++) " " world)
-- اینطور میشد (infix) میانوندی:
-- secondGreeting =
-- hello ++ " " ++ world
با استفاده از ++
به عنوانِ تابع پیشوندی برای secondGreeting
، مجبور شدیم چندتا چیز رو جابجا کنیم. ما با این پرانتزگذاری، شرکتپذیری از راستِ تابع ++
رو تأکید کردیم. به خاطر میانوند بودنِ این تابع، خودتون هم میتونین جهتِ شرکتپذیریش رو چک کنید:
Prelude> :i (++)
(++) :: [a] -> [a] -> [a] -- GHC.Base از
infixr 5 ++
عبارتِ where
، به بیانیهها یه تعریفِ محلی میده که در سطح بالا قابل دسترسی نیستن. به عبارت دیگه، where
داخل main
، یک تعریفی میده که فقط در محدودهی تابع یا بیانیهی بالا سَرِش در دسترسه تا اینکه در کل ماژول مرئی باشه. چیزی که در سطحِ بالا مرئی باشه، در گستره ِ همهی بخشهای یه ماژول قرار داره، و امکانِ صادر شدنش توسطِ ماژول، یا وارد شدنش به ماژولهای دیگه وجود داره. در مقابل، تعاریف محلی فقط برای تابعِ خودشون در دسترساند، نمیشه secondGreeting
رو به یه ماژول دیگه وارد و دوباره ازش استفاده کرد.
برای اینکه بهتر نشون بدیم:
-- print3broken.hs
module Print3Broken where
printSecond :: IO ()
printSecond = do
putStrLn greeting
main :: IO ()
main = do
putStrLn greeting
printSecond
where greeting = "Yarrrrr"
یه پیغام خطا مشابه این میگیرین:
Prelude> :l print3broken.hs
[1 of 1] Compiling Print3Broken
( print3broken.hs, interpreted )
print3broken.hs:6:12: Not in scope: ‘greeting’
Failed, modules loaded: none.
اگه نگاه دقیقتری به این خطا بندازیم:
print3broken.hs:6:12: Not in scope: ‘greeting’
-- [1][2] [3] [4]
۱.
شمارهی سطری که ایراد داشت و باعثِ error شد (در این مورد، ۶).
۲.
ستونی که خطا داشت: ستونِ ۱۲. متونِ کامپیوتر عموماً با سطر و ستون توصیف میشن. شمارهی این سطرها و ستونها به سطرها و ستونهای فایلِ متنی که کُدتون رو توش نوشتین اشاره دارن.
۳.
خودِ مشکل: یه چیزی در گستره نیست، یعنی اون چیز از دیدِ تابعِ printSecond
پنهانه.
۴.
همون چیزی که در گستره نیست.
کاری کنین که Print3Broken
کامپایل شه. باید در دو خط، دو بار نوشتهی “Yarrrrr” رو چاپ کنه.