۳ - ۴تعاریف سطح بالا و محلی
منظور از تعاریف سطح بالا، این نیست که حتماً بالای فایل نوشته شده باشن. وقتی کامپایلر یه فایل رو میخونه، همهی تعاریفِ سطح بالا رو با هم میبینه و ترتیبشون تویِ فایل اهمیتی نداره (البته بعضی محدودیتهایی وجود دارن که بعداً میبینیم). تعاریفِ سطح بالا در گستره ِ کلِ ماژول هستن، و زیرِ هیچ بیانیهی دیگهای تودرتو نشدن.
متضادِ تعاریف سطح بالا، تعاریفِ محلی هستن. چیزی که محلی تعریف شده، یعنی زیر یه بیانیهی دیگه تودرتو شده، و خارج از اون بیانیه قابل دسترسی نیست. در فصلِ قبلی، چند بار با let و where مقادیرِ محلی تعریف کردیم. با مثال زیر دوره میکنیم:
module TopOrLocal where
topLevelFunction :: Integer -> Integer
topLevelFunction x =
x + woot + topLevelValue
where woot :: Integer
woot = 10
topLevelValue :: Integer
topLevelValue = 5اگه از یه ماژول ِ دیگه، ماژول ِ بالا (TopOrLocal) رو وارد کنین، به topLevelFunction و topLevelValue دسترسی پیدا میکنین. ولی woot، خارج از topLevelFunction عملاً نامرئیه. در هسکل، عباراتِ let و where برای انقیاد یا تعریفهای محلی به کار میرن. منظور از انقیاد کردن یا تعریف کردن، دادنِ اسم به یه بیانیهست. میشه توابع رو بینام تعریف کرد و هر دفعه تابع رو تماماً نوشت، اما با نامگذاری و استفاده از اسمِش (بجای کلِ تابع) تکرار کمتر میشه.
نکتهی دیگه اینکه ما برای woot هم، تایپِش رو با گرامر ِ :: زیرِ where صراحتاً نوشتیم. این کار اصلاً لازم نبود (استنتاجِ تایپ ِ هسکل خودش تشخیص میداد)، اما اینجا نوشتیم تا گرامر ِ تایپ سیگنچرِ محلی رو هم دیده باشین. حتماً این کد رو تو REPL بارگذاری و اجرا کنین:
Prelude> :l TopOrLocal.hs
[1 of 1] Compling TopOrLocal
Ok, modules loaded: TopOrLocal.
*TopOrLocal> topLevelFunction 5
20با آرگومانهای دیگه هم امتحان کنین، خودتون هم توی ذهن (یا روی کاغذ) مراحل محاسبات رو انجام بدین تا از درک نتایج حاصل مطمئن بشین.
تمرینها: گستره
۱.
این کُدها در یک جلسه توی REPL نوشته شدن. آیا y در گستره ِ z هست؟
Prelude> let x = 5
Prelude> let y = 7
Prelude> let z = x * y۲.
این کُدها در یک جلسه توی REPL نوشته شدن. آیا h در گستره ِ g هست؟
Prelude> let f = 3
Prelude> let g = 6 * f + h۳.
این نمونه کد از یه فایلِ منبع ِه. آیا برای اجرای area، هر چیزی که لازم داریم در گستره هست؟
area d = pi * (r * r)
r = d / 2۴.
این کد هم از یه فایل منبع ِه. آیا r و d در گستره ِ area هستن؟
area d = pi * (r * r)
where r = d / 2