۲۶ - ۷محاسبهی نااکید قابلیتهامون رو تغییر میده
بعداً با جزئیات بیشتر، ترتیبِ معمولیِ محاسبه (استراتژیِ نااکید که هسکل برای پیادهسازیهاش پیشنهاد کرده) رو توضیح میدیم. الان به چندتا مثال از قابلیتهایی که نااکید بودن میده نگاه میکنیم. این کد با هردو استراتژیِ محاسبه ِ اکید یا نااکید کار میکنه:
Prelude> let myList = [1, 2, 3]
Prelude> tail myList
[2,3]دلیل اینکه هم در زبانهای اکید و هم در زبانها نااکید کار میکنه اینه که چیزی غیرقابل محاسبه نداره. اما با توجه به اینکه undefined (یکی از نمونههای تهی) در صورت اجبار شدن، خطا میده:
Prelude> undefined
*** Exception: Prelude.undefinedیه تفاوت بین اکید بودن و نااکید بودن میبینیم. این کُد فقط در زبانهای نااکید کار میکنه:
Prelude> let myList = [undefined, 2, 3]
Prelude> tail myList
[2,3]به خاطر اون تهی، یه زبانِ اکید سرِ درست کردن ِ myList خطا میداد. دلیلش اینه که زبانهای اکید همهی بیانیهها رو به محض درست شدن محاسبه میکنن. همون لحظهای که [undefined,2,3] تعریف میشد، undefined به عنوانِ یه آرگومان به (:) محاسبه میشد و یه استثنا میداد. در مقابل تو هسکل، محاسبهی نااکید باعث میشد اون مقدارِ تهی تا زمانی که لازم نشده محاسبه نشه.
ببینین آیا میتونین (با دلیل) تشخیص بدین که این مثال استثنا میده یا نه؟
Prelude> head $ sort [1, 2, 3, undefined]وقتی head رو به یه تابع که به sort داده شده اعمال میکنیم، فقط کوچکترین مقدارِ لیست رو لازم داریم، و کل کاری که انجام میشه همینه. مشکل اینجاست که sort برای پیدا کردنِ کمترین مقدار باید undefined رو حساب کنه، که اون هم خطا میده.