سلام به همه دوستان اوبونتویی .
زبان Haskell هم یک زبان Functional خوب هست که هم میتونیم برای نوشتن برنامه های کاربردی(بیشتر برنامه هایی که با الگوریتم ها سر و کار دارند) به کار ببریمش هم به عنوان ماشین حساب ازش استفاده کنیم
.
وبسایت رسمی :
http://haskell.org ویکیپدیای پارسی :
http://fa.wikipedia.org/wiki/%D9%87%D8%B3%DA%A9%D9%84_%28%D8%B2%D8%A8%D8%A7%D9%86_%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3%DB%8C%29برای این که در لینوکس ازش استفاده کنیم باید ghc رو نصب کنیم.
sudo apt-get install ghc
و خب نزدیک ۵۰ مگ دان میکنه و بعد نصب هم نزدیک ۲۰۰ مگ جا روی هارد میگیره. خب برای شروع چی نیاز داریم؟ یک ادیتور متنی و یک ترمینال. خب ادیتور چی پیشنهاد میشه؟ حتی leafpad که در xfce موجوده هم کافیه براش ! . برای شروع به کار با این زبان ، کافیه که ghci رو اجرا کنیم تا بتونیم به عنوان یک ماشین حساب ازش استفاده کنیم :
ghci
و بعدش وارد شل خودش میشه. اینجا میتونید اینها رو تایپ کنید و نتیجه رو ببینید : (البته فکر کنم زوایا رو بر حسب گراد حساب میکنه) :
2+2
sin(45)
cos(30)
tan(60)
2*2^5
5^6
pi
و ببنید که چی به چیه. خب در اینجا هم دو مفهوم «عملگر» و «عملوند» رو داریم باز
عملگرها هم مثل سایر زبانهای برنامه نویسی هستند.
اولین و ساده ترین برنامه :
میخوایم یک برنامه بسازیم ، اونم برای چه کاری؟ محاسبه مساحت یک دایره
خب ابتدا باید یک ادیتور باز کنیم و بعدش :
متغیر تعریف میکنیم (r که معروفه
)
r = 2
و بعد باید یک تابع تعریف کنیم :
area = pi*r^2
یعنی سورس ما چنین شکلی خواهد داشت :
r = 2
area = pi*r^2
خب این رو به نام circle.hs در Desktop ذخیره میکنیم و ghci رو اجرا میکنیم ! بعدش چه کنیم؟ این کدها رو وارد میکنیم :
:cd ~/Desktop
:load circle.hs
بعدش چنانچه در شل جدید که prompt اون Main هست ، تایپ کنیم area مساحت رو نشونمون میده.
این اول کاره ، باقیش باشه بعد
قسمت دوم :
دریافت ورودی از کاربر و قرار دادن توی تابع :
بعضی وقتها پیش میاد که نیاز باشه کاربر یک ورودی به یک تابع بده و ازش خروجی تهیه کنه ، با روش قبلی تنها به این شکل بود که مثلا برای r مقدار ۵ یا هر چیز دیگری (از منفی بی نهایت تا مثبت بی نهایت) رو تعریف میکردیم و برنامه تنها یک خروجی داشت! اما حالا برنامه ای خواهیم نوشت که مقدار رو موقع load شدن از کاربر دریافت کنه !
کل کد ما به این شکل خلاصه میشه :
area r = pi*r^2
این کد رو در فایل circle.hs ذخیره میکنیم.
خب به شیوه قبلی با دستورات :cd و :load برنامه رو کامپایل میکنیم. حالا این ها رو تست کنید :
area 2
area 0.3
area 12
و ببنید چی دریافت میکنید ! البته تابع خالی رو دیگه نمیتونید بهش بدید !
حالا یک تمرین خودتون حل کنید :
یک برنامه برای محاسبه مساحت مثلث بنویسید!
نکته مهم : کدهایی که در پایین میان تفاوتهایی با هم دارند و لازم دونستم حتما بگم!خب یک دایره داریم ، با شعاع ۸ ، حالا میخوایم به ۵+۳ بشکنیمش! در هاسکل کدش اینطور هست :
area (5+3)
و میخوایم به مساحت دایره با شعاع ۵ ، ۳ واحد ناقابل اضافه کنیم :
area 5+3
و میخوایم مساحت دو دایره مماس ، یکی با شعاع ۳ و دیگری ۵ رو با هم جمع کنیم (فرض کنید این دو دایره به هم چسبیدن! مثل مسائل مساحت راهنمایی
).
area 3 + area 5
که البته چون عمل جمع هست ترتیب مهم نیست.
کد اول دارای پرانتز هست و این یعنی حتما برای اینکه ابتدا دو عدد جمع بشه و بعد سایر عملیات ها روش اعمال بشه نیاز به پرانتز داریم ، پرانتز در ریاضی بالاترین اولویت رو داره ، بعدش توان و رادیکال ، بعدش ضرب و تقسیم ، بعدش جمع و تفریق. اگر به دو اولویت مشابه ، مثلا ضرب و تقسیم پشت هم رسیدیم ، از سمت چپ اونی که جلوتر هست رو ابتدا انجام میدیم. کامپیوتر هم همین کار رو میکنه.کد دوم ابتدا مساحت رو حساب میکنه ، بعدش مقدار بعد علامت + رو به مساحت اضافه میکنه، چرا؟ چون فرمول مساحت دارای توان و ضرب هست که طبعا اولویت های بالاتری دارند کد سوم هم که دو مساحت رو جداگانه حساب میکنه و در نهایت ، اونها رو با هم جمع کرده و به ما نشون میده. برای تفریق و ضرب و تقسیم و ... هم به همین شکل عمل کنید. خب یک خبر بد! هاسکل کتانژانت حساب نمیکند! اما برای محاسبه کتانژانت کافیست که یک تابع کتانژانت براش تعریف کنیم. برای محاسبه کتانژانت دو راه هست :
۱- تقسیم عدد یک بر تانژانت
۲- تقسیم کسینوس بر سینوس
چون هاسکل ، امکان محاسبه تانژانت رو داره ، میتونیم همون فایل circle.hs رو ویرایش کنیم و یک تابع جدید براش بنویسیم :
cot(r) = 1/tan(r)
و بعد اون کد رو اجرا کنیم ! (روش اجرا در بالا توضیح داده شد!) .
خب این بار میخوایم بریم سراغ کامپایل برنامه از سورس
.
برای نوشتن سورس اول مثال همیشگی Hello World رو مینویسیم (در یک فایل به نام HelloWrold.hs) .
main = putStr("Hello World!\n")
توضیح:
main ماژول اصلی هست که کامپایلر ازش استفاده میکنه. putStr هم که مشخصه! برای نمایش داده از نوع String به کار میره. دستورات backslash هم اینجا هستند (همه جا هستند
) .
خب فایل رو Save میکنیم و بعد بدین شکل کامپایل مینماییم :
haskell-compiler HelloWorld.hs
یک نمونه پیشرفته تر از همین کد که اسمتون رو میگیره و بهتون سلام میکنه :
main = putStrLn "Waht's your name?">>
getLine>>= \ name ->
putStr("Hello, " ++ name ++ "!\n")
این رو هم کامپایل کنید تا به قدرت هسکل در این زمینه هم پی ببرید.
ان شاء الله بزودی وارد مباحث پیشرفته تر هسکل خواهیم شد، و مواردی رو بیشتر فرا خواهیم گرفت تا بتونیم برنامه های کاربردی تری بنویسیم
.
عملگرهای منظقی :خب یکم چاشنی منطق به کارمون اضافه نکنیم عایا؟
.
اینجا هم عملگرهای منطقی مثل && و || وجود دارند. عملگرهای منطقی، تفاوتی با عملکردها حسابی دارند. تفاوتهای عمده این دو عملگر در این هست که عملگر حسابی، یک مقدار با مقدار دیگر محاسبه میکنه (۴ عمل اصلی) و عملگر منطقی ، اونها رو با هم مقایسه میکنه.
قبل از توضیح بیشتر، بیایم یکم عملگر بازی کنیم
. این عملگر بازی سادست. تنها کافیه که ghci را باز نموده و خروجی این دستورات رو بررسی کنیم :
True && True
و یا
True && False
و یا
True || False
خب عملگرهای منطقی، عدد این چیزا حالیشون نیست
و فقط True و False (یا بهتره بگیم صفر و یک ) میفهمند.
عملگر && به معنای AND و عملگر || به معنای OR هست.
دستورات شرطیدستورات شرطی، مهم ترین بخش زبانهای برنامه نویسی به شمار میان، چون با استفاده از اونها، میشه ورودی ها و خروجی های برنامه رو کنترل کرد و به نتیجه دلخواه رسید. هسکل هم شروط بسیار خوبی داره.
شکل کلی دستور شرطی در هسکل، این هست :
if <condition> then <true_value> else <false_value>
و البته else if هم در این زبان هست، که استفاده اش به این شکله :
if <condition1>
then <true_value1>
else if <condition2>
then <true_value2>
else <false value>
و طبیعتا، میتونید به هر تعدادی که دلتون میخواد else if استفاده کنید.
یک نمونه کد عملیاتی از if then else :
if x == 1 then putStrLn("True") else putStrLn("False")
این کد، موقعی که متغیر x مقداری برابر عدد یک رو دریافت کنه، عبارت «True» و در صورتی که عددی غیر از یک باشه، «False» رو بر میگردونه. البته به روش else if هم میشه آپشن های بیشتری براش در نظر گرفت، مثلا اگر بزرگتر از یک باشه چه کار کنه، اگر کوچکتر باشه چه کار کنه و اگر هیچکدوم از شرایط داده شده رعایت نشد، چه کنه.
اما مثال بهتر از else if مثالی هست که در
یکی از منابع مورد مطالعه پیدا کردم :
describeLetter :: Char -> String
describeLetter c =
if c >= 'a' && c <= 'z'
then "Lower case"
else if c >= 'A' && c <= 'Z'
then "Upper case"
else "Not an ASCII letter"
این یک تابع هست و وظیفه داره تا کوچک و بزرگ بودن حروف رو تعیین کنه. همچنین، اگر ورودی از نوع حروف اسکی نباشه، مقداری که مقابل else تعریف شده، برگردونده میشه.