Ձեր ծրագիրը բավականին «հրամայական» տեսք ունի. դուք սահմանում եք y
փոփոխականը, այնուհետև ինչ-որ կերպ գրում եք do
, որը կանչում է (?) list
ֆունկցիան (?), որն ինքնաբերաբար կարծես «վերադարձնում է y
»-ը և այնուհետև դուք ուզում եմ ավելացնել y
:
Haskell (և առավել ֆունկցիոնալ և դեկլարատիվ) լեզուներն այդպես չեն աշխատում.
- Դեկլարատիվ լեզվով դուք սահմանում եք փոփոխականը միայն մեկ անգամ, արժեքը սահմանելուց հետո, սովորաբար դրա արժեքը փոխելու հնարավորություն չկա,
- Haskell-ում
do
-ը սովորաբար օգտագործվում է մոնադների համար, մինչդեռ length
-ը մաքուր ֆունկցիա է,
let
-ը շարահյուսական կոնստրուկցիա է՝ արտահայտության շրջանակում փոփոխական սահմանելու համար,
- ...
Haskell-ը (կամ որևէ ֆունկցիոնալ լեզու) ծրագրավորելու համար դուք պետք է «մտածեք ֆունկցիոնալ». մտածեք, թե ինչպես կլուծեիք խնդիրը մաթեմատիկական եղանակով՝ օգտագործելով միայն ֆունկցիաները:
Մաթեմատիկայի մեջ դուք կասեք, որ []
դատարկ ցուցակը հստակորեն ունի 0
երկարություն: Ավելին, եթե ցուցակը դատարկ չէ, կա առաջին տարրը («գլուխը») և մնացած տարրերը («պոչը»): Այդ դեպքում արդյունքը մեկ գումարած պոչի երկարությունն է։ Մենք կարող ենք դա վերածել մաթեմատիկական արտահայտության մեջ, ինչպիսին է.
Այժմ մենք կարող ենք հեշտությամբ թարգմանել այդ գործառույթը հետևյալ Haskell կոդի մեջ.
ownLength :: [a] -> Int
ownLength [] = 0
ownLength (_:xs) = 1 + ownLength xs
Այժմ Haskell-ում սովորաբար օգտագործվում են կուտակիչներ՝ պոչի ռեկուրսիա կատարելու համար. դուք փոխանցում եք պարամետր ռեկուրսիվ զանգերի միջոցով և ամեն անգամ, երբ թարմացնում եք: փոփոխականը։ Երբ հասնում եք ձեր ռեկուրսիայի ավարտին, դուք վերադառնում եք, երբեմն որոշ հետմշակումից հետո, կուտակիչ:
Այս դեպքում կուտակիչը կլինի մինչ այժմ տեսած երկարությունը, այնպես որ կարող եք գրել.
ownLength :: [a] -> Int
ownLength = ownLength' 0
where ownLength' a [] = a
ownLength' a (_:xs) = ownLength' (a+1) xs
16.05.2017
length
ը որպես մոնադիկ գործողություն.length xs = sum $ do {xs; return 1}
16.05.2017