۳ - ۴تعاریف سطح بالا و محلی
منظور از تعاریف سطح بالا، این نیست که حتماً بالای فایل نوشته شده باشن. وقتی کامپایلر یه فایل رو میخونه، همهی تعاریفِ سطح بالا رو با هم میبینه و ترتیبشون تویِ فایل اهمیتی نداره (البته بعضی محدودیتهایی وجود دارن که بعداً میبینیم). تعاریفِ سطح بالا در گستره ِ کلِ ماژول هستن، و زیرِ هیچ بیانیهی دیگهای تودرتو نشدن.
متضادِ تعاریف سطح بالا، تعاریفِ محلی هستن. چیزی که محلی تعریف شده، یعنی زیر یه بیانیهی دیگه تودرتو شده، و خارج از اون بیانیه قابل دسترسی نیست. در فصلِ قبلی، چند بار با 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