Hask ell purely functional programming language پروژه زبان برنامه نویسی هسکل ارائه دهنده : علی سواری زیر نظر : استاد سمیه طاهری فر دی ماه 1393 1 Haskell http://haskell.blog.ir/ مقدمه 3 مدل های زبان 4 زبان برنامه نویسی تابعی 5 معرفی زبان برنامه نویسی هسکل 6 توضیح و معرفی پروژه 9 طریقه پاسخگویی 10 کمپایلر هسکل 11 منابع و مراجع 12 2 Haskell  تعصب بی جا همیشه بد است.

Download Report

Transcript Hask ell purely functional programming language پروژه زبان برنامه نویسی هسکل ارائه دهنده : علی سواری زیر نظر : استاد سمیه طاهری فر دی ماه 1393 1 Haskell http://haskell.blog.ir/ مقدمه 3 مدل های زبان 4 زبان برنامه نویسی تابعی 5 معرفی زبان برنامه نویسی هسکل 6 توضیح و معرفی پروژه 9 طریقه پاسخگویی 10 کمپایلر هسکل 11 منابع و مراجع 12 2 Haskell  تعصب بی جا همیشه بد است.

Slide 1

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 2

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 3

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 4

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 5

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 6

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 7

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 8

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 9

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 10

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 11

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 12

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 13

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 14

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 15

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 16

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 17

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 18

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 19

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 20

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 21

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 22

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 23

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 24

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 25

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 26

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬


Slide 27

‫‪Hask‬‬
‫‪ell‬‬

‫‪purely functional programming‬‬
‫‪language‬‬

‫پروژه زبان برنامه نویسی هسکل‬
‫ارائه دهنده‪:‬‬
‫علی سواری‬
‫زیر نظر‪:‬‬
‫استاد سمیه طاهری فر‬
‫دی ماه ‪1393‬‬

‫‪1‬‬

‫‪Haskell‬‬

‫‪http://haskell.blog.ir/‬‬

‫مقدمه‬

‫‪3‬‬

‫مدل‌های‌زبان‬

‫‪4‬‬

‫زبان‌برنامه‌نویسی‌تابعی‬

‫‪5‬‬

‫معرفی‌زبان‌برنامه‌نویسی‌هسکل‬

‫‪6‬‬

‫توضیح‌و‌معرفی‌پروژه‬

‫‪9‬‬

‫طریقه‌پاسخگویی‬

‫‪10‬‬

‫کمپایلر‌هسکل‬

‫‪11‬‬

‫منابع‌و‌مراجع‬

‫‪12‬‬
‫‪2‬‬

‫‪Haskell‬‬

‫‪ ‬تعصب بی‌جا همیشه بد است حتی در برنامه‌نویسی‪ .‬چرا که در‬
‫زمانه‌ای که همه موضوعات تخصصی شده‪ ،‬اصرار بر اینکه یک زبان‬
‫بتواند همه نیازها را رفع کند توقع چندان درستی نیست‪.‬‬
‫‪ ‬ما دانشجویان‪ ،‬برنامه نویسی را نباید فقط در نوشتن کدهایی با‬
‫خروجی ‪ exe‬بدانیم‪ .‬برنامه نویسی با اهداف مختلف نوشته‬
‫می‌شوند‪ ،‬و قاعدتا سبک‌های مختلفی هم دارد‪.‬‬
‫‪ ‬تجربه کار با یک زبان متفاوت مانند زبان تابعی میتواند تأثیر مثبتی‬
‫در دیدگاه ما نسبت به برنامه نویسی داشته باشد‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪3‬‬

‫‪Haskell‬‬

‫زبان‌های‌دستوری‬
‫زبان‌های‌تابعی‬

‫زبان‌های‌قانون‌مند‬
‫زبان‌های‌شی‌گرا‬
‫‪http://haskell.blog.ir/‬‬

‫‪4‬‬

‫‪Haskell‬‬
‫‪ ‬برنامه‌نویسی تابعی نوعی پارادایم برنامه‌نویسی است که در آن‬
‫«محاسبات» به صورت ارزش‌یابی توابع ریاضی در نظر گرفته می‌شوند‪.‬‬
‫‪MATLAB‬را که خیلی مسایل وابسته به‬
‫‪ ‬زبان های تابعی تفاوت بین داده و توابعی‬
‫آنهاست را از میان برداشته است‪.‬‬
‫‪ ‬برنامه نویسی تابعی کوتاه‌تر و دسته‌بندی شده‌تر از سایر انواع زبان است‬
‫همچنین اندازه این برنامه ها و قابلیت خوانایی آنها حتی از زبانهای‬
‫‪Haskell‬‬
‫شی‌گرا نیز بیشتر است‪.‬‬

‫‪Lisp‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪5‬‬

‫‪Haskell‬‬

‫‪ ‬برنامه نویسی تابعی تمام کدها را به صورت مجموعه ای از توابع که‬
‫میتوانند ورودی هایی را دریافت و مقادیری را برگردانند نگاه می‌کند‪.‬‬
‫‪ ‬به جای حلقه تکرار از حلقه های بازگشتی استفاده می‌کند‪.‬‬
‫‪ ‬توابع در برنامه نویسی تابعی بسیار شبیه توابع ریاضی هستند زیرا آنها‬
‫وضعیت برنامه را تغییر نمیدهند‪.‬‬
‫‪ ‬برای مثال طریقه پیاده سازی یک تابع را در یک زبان تابعی ببینید‪:‬‬

‫}‪>3‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪, 𝑥2‬‬

‫‪𝑥 ∈ ℕ‬‬

‫𝑥×‪S = 2‬‬

‫]‪s = [2*x | x <- [0..] , x^2 > 3‬‬
‫‪6‬‬

‫‪Haskell‬‬

‫هسکل‌‌هم‌یک‌زبان‌برنامه‌نویسی‌تابعی‌است‌و‌برای‌‬
‫افرادی‌که‌سر‌و‌کارشان‌با‌فرمولها‌و‌الگوریتمهای‌ریاضی‌‬
‫است‪‌،‬بسیار‌مناسب‌است‪.‬‬
‫هسکل‌(به‌انگلیسی‪Haskell) ‌:‬یک‌زبان‌برنامه‌نویسی‌‬
‫تابعی‌خالص‌و‌کارآمد‌با‌معانی‌ساده‌می‌باشد‌که‌به‌نام‌‬
‫منطق‌دانی‌به‌نام‌هسکل‌کاری‌نام‌گذاری‌شده‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪7‬‬

‫‪Haskell‬‬

‫هسکل‌یک‌زبان‌برنامه‌نویسی‌پیشرفته‌کامالً‌کارآمد‌و‌یک‌محصول‌متن‌باز‌‬
‫است‌که‌حاصل‌بیش‌از‌بیست‌سال‌پیشرفت‌و‌تحقیق‌می‌باشد‌که‌اجازه‌‬
‫توسعه‌سریع‌و‌پیاپی‌سالم‌و‌مختصر‌و‌صحیح‌نرم‌افزار‌را‌می‌دهد‌با‌‬
‫پشتیبانی‌قوی‌از‌یکپارچه‌سازی‌با‌سایر‌زبان‌ها‪‌،‬همزمانی‌داخلی‌ساختمانی‌‬
‫و‌موازی‌کار‌کردن‌و‌پیدا‌کردن‌باگ‌ها‌در‌سورس‌برنامه‌و‌پروفایلر‌و‌‬
‫کتابخانه‌غنی‌و‌ساخت‌نرم‌افزار‌قابل‌انعطاف‌و‌قابل‌نگهداری‌با‌کیفیت‌باال‌را‌‬
‫ساده‌می‌کند‪‌.‬هسکل‌هم‌ساده‌است‌و‌هم‌دید‌ریاضیاتی‌شما‌را‌باال‌میبرد!‌‬
‫پیشنهاد‌میکنم‌این‌زبان‌و‌یا‌زبان‌مشابه‌آن‌را‌حتما‌بررسی‌کنید‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪8‬‬

‫‪Haskell‬‬

‫هاسکل‌کمی‌تنبل‌است‌‪‌،‬درست‌شنیدید!‌تنبل!‌‬
‫میپرسید‌چرا؟‌برای‌این‌که‌این‌زبان‌یک‌تابع‌که‌شما‌‬
‫نوشته‌اید‌را‌‪‌،‬تنها‌زمانی‌اجرا‌میکند‌که‌فراخوانی‌‬
‫شود‪‌.‬در‌زمان‌دیگری‌آن‌تابع‌اجرا‌نمیشود‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪9‬‬

‫‪Haskell‬‬
‫‪ ‬زبان هسکل روشهای زیبا و منحصر به فردی را برای بسیاری از‬
‫مسائل کامپیوتری ایجاد می‌کنند‪.‬‬
‫‪ ‬برای مثال تابع فاکتوریل را به سه روش زیر ببینید‪:‬‬

‫روش‬
‫بامزه!‬

‫روش‬
‫کالسیک‬
‫‪fac 0 = 1‬‬

‫) ‪fac n = n * fac ( n - 1‬‬

‫]‪fac n = product [1.. n‬‬

‫یا در یک خط‬
‫‪http://haskell.blog.ir/‬‬

‫‪fac n = if n> 0 then n * fac (n-1) else 1‬‬
‫‪10‬‬

‫‪Haskell‬‬

‫‪‬‬

‫پس از عرضه زبان برنامه نویسی میراندا توسط شرکت انگلیسی ‪Research‬‬
‫‪Software Ltd‬در سال ‪ 19۸5‬عالقه به زبان‌های اصلی کند افزایش پیدا کرد‪.‬‬
‫در سال ‪ 19۸5‬بیش از دو زبان برنامه نویسی خالص و کارآمد با معانی ساده وجود‬
‫داشت‪ .‬بین این زبان نشستی برگزار شد که در طی آن شرکت کننده‌ها به توافق‬
‫قطعی رسیدند که یک کمیته باید شکل بگیرد که وظیفه آن تعریف استانداردهای‬
‫بازی برای زبان‌های این چنینی باشد این کار با هدف صریح یکی کردن زبان‌های‬
‫موجود به یک زبان مشترک به کار می‌رود‪ ،‬به منظور ایجاد پایه‌ای تحقیقات‬
‫آیندگان در طراحی زبان انجام شد اولین نسخه زبان در سال ‪ 1990‬نتیجه‬
‫تالش‌های کمیته در سری تعاریف زبان در اواخر ‪ 199۸‬به حد اعلی رسید‪ ،‬که بر‬
‫آن بود که یک نسخه زبان پایدار‪ ،‬کوچک و قابل حمل که یک کتابخانه استاندارد‬
‫برای تدریس ضمیمه آن بود و همچنین پایه‌ای برای تکامل‌ها در آینده باشد‪ ،‬را‬
‫تعیین کند کمیته صریحاً از به وجود آمدن تکامل‌های اضافی و مغایر با از راه‬
‫اضافه کردن و بهم پیوستن طرح‌های تجربی استقبال کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪11‬‬

‫‪Haskell‬‬
‫‪ ‬در ژانویه ‪ 1999‬استانداردهای زبان به صورت نسخه معتبر و اصلی با نام‬
‫‪Haskell 98 Language and Libraries: The‬‬
‫‪Revised Report‬منتشر شد یک نسخه اصالح شده با نام منتشر‬
‫شد به خاطر پیاده‌سازی استاندارد حال حاضر را به نمایش می‌گذارد‪.‬‬
‫‪ ‬تکامل‌ها و خصیصه‌ها خصیصه بارز زبان هسکل شامل تطبیق الگو‪ ،‬قوه‬
‫ادراک به صورت لیست‪ ،‬حائل‌ها‪ ،‬عملگرهای قابل تعریف و تک گماری‬
‫است‪.‬‬
‫‪ ‬این زبان همچنین قابلیت پشتیبانی از تابع‌های بازگشت پذیر را دارد و‬
‫انواع داده‌های جبری را به خوبی ارزیابی می‌کند و همچنین شامل یکه‌ها و‬
‫کالس‌های الگو می‌باشد‪.‬‬
‫‪ ‬ترکیب این خصیصه‌ها می‌تواند توابعی بسازد که نوشتن آن بوسیله‬
‫زبان‌های برنامه نویسی روندی دشوار است اما انجام آن در ایت زبان جزئی‬
‫و آسان است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪12‬‬

‫‪Haskell‬‬

‫کمپایلر‌هسکل‌و‌برخی‌‬
‫کدهای‌آن‌شـبـاهتهایی‌با‬
‫محـیط‌ ‪CMD‬ویــنـدوز‌و‌‬
‫یـا‌ترمینال‌یونیکس‌دارد‪.‬‬
‫برای‌ادیت‌کدها‌و‌نوشتن‌‬
‫توابع‌می‌توان‌از‌یک‌نوتپد‌‬
‫ساده‌استفاده‌کرد‪.‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪13‬‬

Haskell

http://haskell.blog.ir/

14

‫‪Haskell‬‬
‫‪ ‬شبکه‌شتاب‌برای‌بررسی‌درست‌بودن‌شماره‌کارت‌ها‌از‌یک‌چک‌سام‌ساده‌‬
‫استفاده‌می‌کند‪‌.‬نحوه‌محاسبه‌این‌چک‌سام‌به‌این‌صورت‌است‪:‬‬
‫‪ ‬اول‪‌:‬ترتیب‌اعداد‌شماره‌کارت‌معکوس‌میگردد‪.‬‬
‫‪ ‬اعداد‌از‌راست‌یکی‌در‌میان‌دو‌برابر‌شوند‪(‌.‬یعنی‌عدد‌اول‌دوبرابر‌شود‌عدد‌‬
‫دوم‌تغییر‌نکند‪‌،‬عدد‌سوم‌دو‌برابر‌شود‌و‪)...‬‬
‫‪ ‬تمام‌اعداد‌یک‌رقمی‌شده‌و‌جمع‌می‌شوند‪(‌.‬یعنی‌برای‌اعداد‌دو‌رقمی‌جمع‌‬
‫اعداد‌حساب‌شود‌و‌نه‌خود‌اعداد)‬
‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‌عدد‌چک‌سام‌صحیح‌است‌و‌‬
‫در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪15‬‬

Haskell
.‫ در‌ابتدا‌عدد‌باید‌آرایه‌گردد‬

21362557822213
[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
http://haskell.blog.ir/

16

‫‪Haskell‬‬

‫ایجاد یک آرایه از‬
‫باقیمانده تقسیم ‪x‬بر ‪10‬‬

‫شناسه خروجی‬
‫آرایه‬
‫از نوع ‪Integer‬‬

‫شناسه ورودی‬
‫از نوع‬
‫‪Integer‬‬

‫نام تابع‪:‬‬
‫‪toDigits‬‬

‫]‪toDigits :: Integer -> [Integer‬‬
‫‪toDigits x‬‬
‫]‪| x > 0 = toDigits (div x 10) ++ [mod x 10‬‬
‫][ = ‪| otherwise‬‬
‫نام متغیر‬

‫اضافه کردن عدد قبلی به‬
‫آرایه‬
‫ارسال نتیجه تقسیم ‪x‬بر‬
‫‪ 10‬به خود تابع (تابع‬
‫بازگشتی)‬

‫شرط انجام دادن این‬
‫خط‬
‫(در صورت ‪false‬‬
‫بودن به خط بعد‬
‫میرود)‬

‫ورودی‬

‫‪http://haskell.blog.ir/‬‬

‫‪17‬‬

Haskell

[2,1,3,6,2,5,5,7,8,2,2,2,1,3]
[3,1,2,2,2,8,7,5,5,2,6,3,1,2]

http://haskell.blog.ir/

18

‫‪Haskell‬‬

‫تابع قبلی فراخوانی شده و نتیجه‬
‫به جای خود تابع قرار میگیرد‪.‬‬

‫]‪toDigitsRev :: Integer -> [Integer‬‬
‫‪toDigitsRev x‬‬
‫)‪| x > 0 = reverse (toDigits x‬‬
‫][ = ‪| otherwise‬‬

‫از کلمات کلیدی خود زبان‬
‫هسکل که آرایه را معکوس‬
‫میکند‪.‬‬

‫خط دوم به این دلیل اضافه شد که اگر‬
‫ورودی صفر و یا کوچکتر بود براکت‬
‫خالی چاپ کند‬

‫‪http://haskell.blog.ir/‬‬

‫‪19‬‬

Haskell

[3,1,2,2,2,8,7,5,5,2,6,3,1,2]
[6,1,4,2,4,8,14,5,10,2,12,3,2,2]

http://haskell.blog.ir/

20

‫‪Haskell‬‬

‫]‪:: [Integer] -> [Integer‬‬
‫][ = ][‬
‫]‪(x:[]) = [x*2‬‬
‫]‪(x:[y]) = [x*2] ++ [y‬‬
‫‪(x:y:xy) = [x*2]++ [y]++ doubleEveryOther xy‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬
‫‪doubleEveryOther‬‬

‫از قابلیت های هسکل این است که یک تابع را می توان‬
‫چندین مرتبه با نتایج مختلف نوشت‪ .‬مثال خط دوم این کد را‬
‫ببینید! وقتی ورودی براکت خالی بود براکت خالی را‬
‫بازمیگرداند‪ .‬خط سوم وقتی ورودی یک متغیر داشته باشد‪.‬‬
‫خط چهارم وقتی که ورودی دو متغیر داشته باشد‪ . .‬خط‬
‫چهارم برای تعداد بیشتر‪ .‬عالمت دو نقطه در این جا عدد‬
‫نخست دورن براکت را گرفته و در خود نگه میدارد‪.‬‬
‫‪21‬‬

Haskell

[6,1,4,2,4,8,14,5,10,2,12,3,2,2]
6+1+4+2+4+8+1+4+5+1+0+2+1+2+3+2+2

= 48
http://haskell.blog.ir/

22

‫‪Haskell‬‬

‫‪:: [Integer] -> Integer‬‬
‫‪[] = 0‬‬
‫)‪(x:[]) = (mod x 10) + (div x 10‬‬
‫‪(x:xy) = ((mod x 10) + (div x 10)) + sumDigits xy‬‬

‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬
‫‪sumDigits‬‬

‫با توجه به اینکه در این برنامه به صورت مشخص‬
‫اعدادی که ضرب در ‪ 2‬شدند به هیچ وجه نمی تواند‬
‫بزرگتر از ‪ 18‬باشند کار ما بسیار ساده شده است‪.‬‬
‫پس در هر مرحله مقسوم علیه و باقیمانده تقسیم بر‬
‫‪ 10‬اعداد با هم جمع می شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪23‬‬

‫‪Haskell‬‬

‫‪−‬‬

‫‪ ‬اگر‌عدد‌به‌دست‌آمده‌بر‌‪ 10‬بخش‌پذیر‌باشد‬
‫عدد‌چک‌سام‌صحیح‌است‬
‫و‌در‌غیر‌اینصورت‌شماره‌کارت‌غلط‌است‪.‬‬

‫‪48‬‬

‫⊢‬

‫‪48 10‬‬
‫‪40 4‬‬
‫‪(8 == 0) ? False‬‬
‫‪8‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪24‬‬

‫‪Haskell‬‬

‫‪ ‬در‌این‌مرحله‌که‌مرحله‌نهایی‌است‌خروجی‌تابع‌از‌جنس‌بولین‬
‫است‪‌.‬این‌تابع‌تمام‌توابع‌را‌درون‌خود‌ترکیب‌کرده‌است‪‌.‬یعنی‌هر‌‬
‫تابعی‌درون‌آن‌یک‌تابع‌فراخوانی‌شده‌و‌تابع‌نتیجه‌خود‌را‌به‌تابع‌‬
‫بیرونی‌میدهد‪.‬‬
‫در‌پایان‌نتیجه‌که‌باقیمانده‌تقسیم‌بر‌ده‌است‌را‌با‌صفر‌مقایسه‌‬
‫میکنیم‪‌.‬و‌خروجی‌‪ True‬و‌یا‌‪ False‬را‌بازمیگرداند‪.‬‬
‫‪validate :: Integer -> Bool‬‬
‫‪validate x = (mod (sumDigits (doubleEveryOther (toDigitsRev x))) 10) == 0‬‬

‫‪http://haskell.blog.ir/‬‬

‫‪25‬‬

‫‪Haskell‬‬
‫عبارت ‪Prelude‬در‬
‫واقع ‪Prompt‬‬
‫شل ‪ ghci‬است‪.‬‬
‫برای انتقال به‬
‫دایرکتوری خاص از‬
‫‪ ‬برای‌کمپایل‌کردن‌الزم‌است‌یک‌نوتپد‌را‌باز‌کنیم‌تمام‌کدها‌را‌در‌‬
‫کد ‪ :cd‬استفاده‬
‫فراخوانی‬
‫آن‌وارد‌میکنیم‪‌.‬سپس‌با‌فرمت‌‪ hs‬مثال‌در‌دستکتاپ‌ذخیره‌ فایل تابع را‬
‫میکنیم‪.‬‬
‫میکنیمرا تائید‬
‫کمپایلر مدل‬
‫میکنیم‪‌.‬سپس‪...‬‬
‫میکند نوشته‬
‫حاال از توابع‬
‫شده میتوانیم استفاده‬
‫کنیم‪.‬‬
‫یکی یکی آنها را‬
‫آزمایش میکنیم‪ .‬تابع‬
‫را می نویسیم و‬
‫ورودی مورد نیاز را‬
‫روبروی آن‬
‫مینویسیم‪ .‬خروجی در‬
‫خط بعد چاپ می‬
‫شود‪.‬‬
‫‪http://haskell.blog.ir/‬‬
‫‪26‬‬

‫‪Haskell‬‬

‫‪‬‬

‫با‌توجه‌به‌محدود‌بودن‌بسیار‌زیاد‌منابع‌فارسی‌مطالب‪‌،‬فایل‌پاورپوینت‪‌،‬توضیحات‪‌،‬عنوان‌پروژه‌و‌‬
‫توضیحات‌مربوط‌به‌آن‌در‌وبالگ‌زیر‌درج‌شده‌اند‪:‬‬

‫‪http://haskell.blog.ir/‬‬
‫‪http://haskell.blog.ir/‬‬

‫‪27‬‬