۳ - ۶الحاق و گستره

از پرانتز استفاده می‌کنیم تا تابعِ ‏‎++‎‏ رو به صورت پیشوندی (و نه میانوندی) استفاده کنیم:

-- 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” رو چاپ کنه.