рдЖрд▓рд╕реА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ

рд╣рд╛рд╕реНрдХреЗрд▓ рдХреЗ "рдХреЙрд▓рд┐рдВрдЧ рдХрд╛рд░реНрдб" рдореЗрдВ рд╕реЗ рдПрдХ рд╕реНрдердЧрд┐рдд, рдпрд╛ рдЖрд▓рд╕реА, рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рд╣реИред рднрд╛рд╖рд╛ рдХреА рдпрд╣ рд╡рд┐рд╢реЗрд╖рддрд╛ рди рдХреЗрд╡рд▓ рдХрдИ рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЛ рдЦреЛрд▓рддреА рд╣реИ, рдмрд▓реНрдХрд┐ рдХреБрдЫ рд╕рдорд╕реНрдпрд╛рдПрдВ рднреА рдкреИрджрд╛ рдХрд░рддреА рд╣реИ, рдЦрд╛рд╕рдХрд░ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреА рдЧрддрд┐ рдХреЗ рд╕рд╛рдеред

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдпрд╣ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛: рдЖрд▓рд╕реА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреНрдпрд╛ рд╣реИ, рдЙрдирдХрд╛ рдХреНрдпрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдкреНрд░рджрд░реНрд╢рди рд╣рд╛рдирд┐ рд╕реЗ рдХреИрд╕реЗ рдмрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЖрд▓рд╕реА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреНрдпрд╛ рд╣реИ?


рд╕рд╛рдорд╛рдиреНрдп, рдЖрд▓рд╕реА рдирд╣реАрдВ, рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ, рдЧрдгрдирд╛рдПрдВ рд╕рдЦреНрдд рд╣реИрдВ - рдЕрд░реНрдерд╛рдд, рдлрд╝рдВрдХреНрд╢рди рдХреЗ рддрд░реНрдХреЛрдВ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреБрдЫ рд╕рд╛рд░ рд╕рдЦреНрдд рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдореЗрдВ:

max(5+3, 4*4) ->
max(8, 4*4) ->
max(8, 16)
16


рдФрд░ рд╣рд╕реНрдХреЗрд▓ рд╕рд╣рд┐рдд рдЖрд▓рд╕реА рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ, рдЧрдгрдирд╛рдПрдВ рд╕реНрдердЧрд┐рдд рдХрд░ рджреА рдЬрд╛рддреА рд╣реИрдВред рд╕рднреА рдЧрдгрдирд╛ (рдХреБрдЫ I / O рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░) рддреБрд░рдВрдд рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдиреЗ рддрдХ рд╕реНрдердЧрд┐рдд рдХрд░ рджреА рдЬрд╛рддреА рд╣реИрдВред
рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдПрдХ рд╣реА рдЙрджрд╛рд╣рд░рдг:

max (5+3) (4*4) ->
let x = 5+3; y = 4*4 in if x >= y then x else y ->
let x = 8; y = 4*4 in if 8 >= y then 8 else y ->
let x = 8; y = 16 in if 8 >= 16 then 8 else 16 ->
16


рдпрд╣ рдЙрджрд╛рд╣рд░рдг рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдЙрдк-рд╕рдВрджрд░реНрднреЛрдВ (5 + 3 рдФрд░ 4 * 4) рдХреА рдЧрдгрдирд╛ рдХреЛ рдЕрдВрддрд┐рдо, рдЕрд░реНрдерд╛рддреН рдЙрд╕ рдХреНрд╖рдг рддрдХ рд╕реНрдердЧрд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬрдм рддрдХ рдХрд┐ рдЙрдирдХреА рддреБрд▓рдирд╛ рдирд╣реАрдВ рдХреА рдЬрд╛рдиреА рдереАред
рдпрд╣рд╛рдВ, рдЧрдгрдирд╛ рдХреЛ рд░рди рдмрдирд╛рдиреЗ рд╡рд╛рд▓реЗ "рдмрд▓" рдХреЛ рдХрдВрд╕реЛрд▓ рдкрд░ рдЖрдЙрдЯрдкреБрдЯ рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддред рдЖрдИрдУред рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред

рд╡рд╛рджреЗ


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ рд▓реЗрдВ:

let z = (sum [1..10], reverse "haskell") in ...
(рдЖрдЧреЗ рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ z рдХрд╛ рдЙрдкрдпреЛрдЧ рднрд╛рдЧ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛)

z рдПрдХ рд╡рд╛рджрд╛ (engред рдердВрдХ) рд╣реИ, рдмрд╕ рдПрдХ рдЧрдгрдирд╛ рдореВрд▓реНрдп рдирд╣реАрдВ рд╣реИред
рдФрд░ рдЕрдЧрд░ рд╣рдо рдирдореВрдирд╛ z рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░реЗрдВрдЧреЗ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛?

 let z = (sum [1..10], reverse "haskell") (x, y) = z in ... 

рдкрд╣рд▓реЗ, z рдПрдХ рд╕рд░рд▓ рд╡рд╛рджрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╣реИ, рд▓реЗрдХрд┐рди рддрд╛рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХреЗ рдХрд┐ z рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреИрдЯрд░реНрди рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ, рдЙрд╕реЗ z рдХреЛ рдлрд╝реЙрд░реНрдо рдореЗрдВ "рд╡рд┐рд╕реНрддрд╛рд░" рдХрд░рдирд╛ рд╣реЛрдЧрд╛: (**, **) ред x рдФрд░ y рдпреБрдЧреНрдо z рдХреЗ рдШрдЯрдХреЛрдВ рдХреЗ рдЕрдиреБрд░реВрдк рд╡рд╛рджреЗ рд╣реИрдВред
рдирдореВрдиреЗ рдХреЗ рд╕рд╛рде рдПрдХ рдФрд░ рддреБрд▓рдирд╛ рдЬреЛрдбрд╝реЗрдВ:

 let z = (sum [1..10], reverse "haskell") (x, y) = z 'l':ys = y in ... 

рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ y рдПрдХ рд╕реВрдЪреА рд╣реИ, рд╕рдВрдХрд▓рдХ рдЗрд╕рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдлреЙрд░реНрдо рдореЗрдВ ** : ** : ** : **
рдлрд┐рд░, рд╡рд╣ рдкрд╣рд▓реЗ рд╡рд╛рджреЗ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ: 'l' : **
рдФрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ y 'l' рд╕реЗ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдПрдХ рд╕реВрдЪреА рд╣реИ, рдпрд╣ рдкреИрдЯрд░реНрди рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ: 'l':ys = 'l':**
рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, y рдмрд╛рдХреА рд╕реВрдЪреА y рдХреЗ рдЕрдиреБрд░реВрдк рд╡рд╛рджрд╛ рд╣реЛрдЧрд╛ред

рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╕рднреА рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ z рдХреЗ рд▓рд┐рдП рдЧрдгрдирд╛ рдХреА рдЧрд╣рд░рд╛рдИ рдХреИрд╕реЗ рдмрджрд▓ рдЧрдИ рд╣реИ:

**
(**, **)
(**, 'l':**)


z рдХреА рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдЧрдгрдирд╛ рдХреА рдЧрдИ рдереА, рдФрд░ рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рд▓рдЧрднрдЧ рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЫреЛрдЯреА рд╕рдВрднрд╡ рдЧрдгрдирд╛ рдХреЗрд╡рд▓ рдирд┐рд░реНрдорд╛рддрд╛ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ: (**, **) ред рдПрдХ рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП, рдпрд╣ **:** рдпрд╛ [] рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕ рдлрд╛рд░реНрдо рдХреА рд╕рдВрдЦреНрдпрд╛ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ - рд╡реЗ рдпрд╛ рддреЛ рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИрдВ рдпрд╛ рдирд╣реАрдВред
рдЬрдм рдореВрд▓реНрдп рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЧрдгрдирд╛ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИ, рддреЛ рд╡реЗ рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХрдордЬреЛрд░ рд╣реЗрдб рдиреЙрд░реНрдорд▓ рдлреЙрд░реНрдо (WHNF) рдореЗрдВ рд╣реИ, рдФрд░ рдЬрдм рдкреВрд░реА рддрд░рд╣ рд╕реЗ, рддрдм рдиреЙрд░реНрдорд▓ рдлреЙрд░реНрдо рдореЗрдВ ред WHNF рдореЗрдВ рдореВрд▓реНрдп, рдЬрдм рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рддреЛ "рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рдореЗрдВ" рдЪрд▓рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╣рдо рд╕реНрдХреНрд░реАрди рдкрд░ z рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЙрд╕рдХрд╛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╣реЛрдЧрд╛ (55,"lleksah") ред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдРрд╕реЗ рдорд╛рди рдЬрд┐рдирдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рдкрд╛рд╕ рдХреЛрдИ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИ, рд╡реЗ WHNF рдореЗрдВ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗред рдЕрд░реНрдерд╛рддреН, рдкреНрд░рдХрд╛рд░ рдЬреИрд╕реЗ рдХрд┐ рдмреВрд▓, рдСрд░реНрдб, рдЗрдВрдЯ, рдЖрджрд┐ рдореЗрдВ WHNF рдирд╣реАрдВ рд╣реИ, рдФрд░ рдкреНрд░рдХрд╛рд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, [a], рдпрд╛ рддреЛ, рдЖрджрд┐ред рдХреА рд╣реИред

рдЖрд▓рд╕реА рдХрд╛рд░реНрдп


рдХрд╛рд░реНрдп рдЙрдирдХреЗ рддрд░реНрдХреЛрдВ рдореЗрдВ рдЖрд▓рд╕реА рдФрд░ рд╕рдЦреНрдд рд╣реИрдВред рдЖрд▓рд╕реА - рдЙрдирдХреЗ рддрд░реНрдХреЛрдВ рдХреА рдЧрдгрдирд╛ рди рдХрд░реЗрдВ, рдФрд░ рд╕рдЦреНрдд - рдЧрдгрдирд╛ рдХрд░реЗрдВ, рдХрд┐рд╕реА рднреА рдЧрд╣рд░рд╛рдИ рддрдХред рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рддрд░реНрдХ рдореЗрдВ рдЖрд▓рд╕реА рдФрд░ рджреВрд╕рд░реЗ рдореЗрдВ рд╕рдЦреНрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдмреЗрд╢рдХ, рдЕрдзрд┐рдХрд╛рдВрд╢ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрд┐рд╕реА рддрд░рд╣ рдЕрдкрдиреЗ рддрд░реНрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдЙрдирдХреА рдЧрдгрдирд╛ рдХрд╛ рдЕрд░реНрде рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд▓рдВрдмрд╛рдИ рдХрд╛рд░реНрдпред рд╕реВрдЪреА рдХреА рд▓рдВрдмрд╛рдИ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрд╕реЗ рдЕрдкрдиреЗ рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреА рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рдореВрд▓реНрдпреЛрдВ рдХреА рдирд╣реАрдВред рдЕрд░реНрдерд╛рддреН, length ** рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ "рд╡рд┐рд╕реНрддрд╛рд░" рдХрд░реЗрдЧрд╛: length (** : ** : ** : []) ред

рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХрд╛ рдПрдХ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рдХреЛрдИ рдлрд╝рдВрдХреНрд╢рди рдХрд┐рд╕реА рддрд░реНрдХ рдореЗрдВ рдЖрд▓рд╕реА рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рддрд░реНрдХ рдХреЗ рдмрдЬрд╛рдп рдЗрд╕реЗ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдкрд░рд┐рдгрд╛рдо рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реИ, рддреЛ рдЗрд╕ рддрд░реНрдХ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рд╕рдЦреНрдд рд╣реИ, рдФрд░ рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдпрд╣ рдЖрд▓рд╕реА рд╣реИред
рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реЛрдЧреА:

const 5 undefined
Just undefined


рдФрд░ рдпреЗ рдкрд░рд┐рдгрд╛рдо рджреЗрдЧрд╛:

length undefined
head undefined


рдЖрд▓рд╕реА рдкреИрдЯрд░реНрди рддреБрд▓рдирд╛


рди рдХреЗрд╡рд▓ рдХрд╛рд░реНрдп рдЖрд▓рд╕реА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдирдореВрдиреЗ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрд╕ рдирдореВрдиреЗ рдХреА рд╕рдЦреНрдд рддреБрд▓рдирд╛ рдХреЗ рд╡рд┐рдкрд░реАрдд рдЬрд┐рд╕рдХреА рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдЬрд╛рдВрдЪ рдХреА рд╣реИ, рдЖрд▓рд╕реА рд▓реЛрдЧ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд╡рд╛рджреЗ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рдд, рд╡реЗ рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди рдЙрдиреНрд╣реЗрдВ "рддреИрдирд╛рдд" рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

> let f ~(x, y) = 1
> f undefined
1


рдпрд╣рд╛рдБ ~(x, y) рдЖрд▓рд╕реА рдкреИрдЯрд░реНрди рд╣реИред рдЗрд╕рдореЗрдВ рдПрдХ рдЖрд▓рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рддрд░реНрдХ рдХреЗ рд╕рдорд╛рди рд╕рдВрдкрддреНрддрд┐ рд╣реИ: рдЬрдм рд╣рдо рд╡рд╣рд╛рдВ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧреБрдЬрд░рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред
рдПрдХ рдирдореВрдиреЗ рдХреЗ рд╕рд╛рде рдЗрд╕ рддрд░рд╣ рдХреА рддреБрд▓рдирд╛ Control.Arrow рдореЗрдВ рдорд┐рд▓ рд╕рдХрддреА рд╣реИ:

(***) fg ~(x, y) = (fx, gy)

> (const 1 *** const 2) undefined
(1, 2)


рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдпрд╣ рдпрд╛рдж рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЖрд▓рд╕реА рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рддрднреА рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдм рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рдирд┐рд░реНрдорд╛рддрд╛ рд╣реЛред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

head' :: [a] -> a
head' ~[] = undefined
head' ~(x:xs) = x


рдЪреВрдБрдХрд┐ рд╣рдордиреЗ рдмрддрд╛рдпрд╛ рдХрд┐ рдЬрдм рддрдХ рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ рддрдм рддрдХ рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рд╕рд╛рдордиреЗ рдХреНрдпрд╛ рд╣реИ: рдПрдХ рдЦрд╛рд▓реА рд╕реВрдЪреА рдпрд╛ рдЗрд╕рдХреЗ рд▓рд┐рдВрдХ рдореЗрдВ рд╕реЗ рдПрдХред рдлрд╝рдВрдХреНрд╢рди рд╣рдореЗрд╢рд╛ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдкрд╣рд▓реА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рд╣рдордиреЗ рдПрдХ рдЕрдХрд╛рдЯреНрдп рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ред

рдЖрд▓рд╕реА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдорд╛рдВрдЧ рдХреА рдЧрдгрдирд╛

рдЖрд▓рд╕реА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХрд╛ рд╕рдмрд╕реЗ рд╕реНрдкрд╖реНрдЯ рдкреНрд▓рд╕ рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдХреБрдЫ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕рдХреА рдЧрдгрдирд╛ рдирд╣реАрдВ рдХреА рдЬрд╛рдПрдЧреАред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

(&&) False _ = False
(&&) True a = a


рдпрджрд┐ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрд╣рд▓рд╛ рддрд░реНрдХ рдЧрд▓рдд рд╣реИ, рддреЛ рджреВрд╕рд░реЗ рдХреА рдЧрдгрдирд╛ рдХреНрдпреЛрдВ рдХрд░реЗрдВ рдпрджрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдкрд░рд┐рдгрд╛рдо рдЧрд▓рдд рд╣реЛрдЧрд╛? рд╢рд╛рдпрдж рджреВрд╕рд░реЗ рддрд░реНрдХ рдХреЗ рдЕрд░реНрде рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдмрд╣реБрдд рд╕рдордп рд▓реЗрдиреЗ рд╡рд╛рд▓реА рдЧрдгрдирд╛рдУрдВ рдХреЛ рд▓реЗ рдЬрд╛рдПрдЧрд╛, рдЬрд┐рдиреНрд╣реЗрдВ рд▓реИрдВрд╕ рд╕рдВрддреБрд▓рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯрд╛рд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдЖрдк 3 рд╕рдмрд╕реЗ рдЫреЛрдЯреА рд╕реВрдЪреА рдЖрдЗрдЯрдо рдвреВрдВрдврдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ, рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

take 3 (sort xs)

рд▓реЗрдХрд┐рди рдПрдХ рд╕рдЦреНрдд рднрд╛рд╖рд╛ рдореЗрдВ, рдпрд╣ рдмреЗрдХрд╛рд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рдкреВрд░реА рд╕реВрдЪреА рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдЖрд▓рд╕реА рдЧрдгрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде, рд╣рдо рд╕реВрдЪреА рдХреЛ рддреАрд╕рд░реЗ рддрддреНрд╡ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреНрд░рдордмрджреНрдз рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЧрдгрдирд╛ рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИред

Memoization

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдп рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

plus a = a+a

> plus (5+3)
16


5 рдФрд░ 3 рдХрд╛ рдпреЛрдЧ рдХрд┐рддрдиреА рдмрд╛рд░ рдЧрдгрдирд╛ рдХреА рдЧрдИ рд╣реИ? рд╕рд╣реА рдЙрддреНрддрд░: рдПрдХ рдмрд╛рд░ред рдкрд╣рд▓реЗ (5 + 3) - рд╕рд┐рд░реНрдл рдПрдХ рд╡рд╛рджрд╛, рд▓реЗрдХрд┐рди рдЬрдм рдЗрд╕реЗ рдкреНрд▓рд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдЗрд╕рдХреА рдЧрдгрдирд╛ рдХреА рдЧрдИ рдереА рдФрд░ рдЙрдирдХреЗ рдЬрд╡рд╛рдм рдиреЗ рд╡рд╛рджреЗ рдХреЛ рд╣реА рдмрджрд▓ рджрд┐рдпрд╛ред рдЬрдм рджреВрд╕рд░реА рдмрд╛рд░ рдХрд┐рд╕реА рдХреЗ рдореВрд▓реНрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдиреЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЧрдгрдирд╛ рдХреЗ, рдкреВрд░реНрд╡ рдХреЗ рд╡рд╛рджреЗ рд╕реЗ рддреИрдпрд╛рд░ рдкрд░рд┐рдгрд╛рдо рд▓рд┐рдпрд╛ред рдпрд╣ рдЖрд▓рд╕реА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреЗ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЧреБрдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ - рд╕рдВрд╕реНрдорд░рдгред рдПрдХ рдЖрд▓рд╕реА рднрд╛рд╖рд╛ рдореЗрдВ рдПрдХ рд╡рд╛рджрд╛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдлрд┐рд░ рдЧрдгрдирд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдо "рд╡рд╛рджреЗ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдЯ" рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдмрд╕ рдлрд┐рд░ рд╕реЗ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдмрд┐рдирд╛, рдЙрддреНрддрд░ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рддрд╛ рд╣реИред
рдЖрд▓рд╕реА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреА рдпрд╣ рд╕рдВрдкрддреНрддрд┐ рдбрд╛рдпрдиреЗрдорд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдвреВрдВрдврддреА рд╣реИ, рдЬрд┐рд╕реЗ рдЖрд░реНрдЯрд┐рдХрд▓ рдбрд╛рдпрдиреЗрдорд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдФрд░ рд▓реЗрдЬреА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдЕрдирдВрдд рдФрд░ рд▓реВрдкрд┐рдВрдЧ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдВ

рдЖрд╕реНрдердЧрд┐рдд рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХрд╛ рдПрдХ рдФрд░ рдХрд╛рдлреА рдкреНрд░рд╕рд┐рджреНрдз рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдЕрдирдВрдд рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╣реИред

> [1, 3..] !! 10
21


рдпрд╣рд╛рдВ рд╣рдо рд╡рд┐рд╖рдо рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рдПрдХ рдЕрдВрддрд╣реАрди рд╕реВрдЪреА рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕рдХреЗ 10 рд╡реЗрдВ рддрддреНрд╡ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВред

рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ:

> fibs = 1:1:zipWith (+) fibs (tail fibs)
> fibs !! 100
573147844013817084101


рдЕрдирдВрдд рд╕реВрдЪрд┐рдпрд╛рдБ рдмрдирд╛рдирд╛ рдХреЗрд╡рд▓ рдЗрд╕рд▓рд┐рдП рд╕рдВрднрд╡ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЙрдирдХреА рдЧрдгрдирд╛ рддреБрд░рдВрдд рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИред рджреВрд╕рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдлрд╛рдЗрдм рдкрд╣рд▓реЗ 1:1:** , рд▓реЗрдХрд┐рди рдЬрдм рд╣рдо рдЗрд╕ рд╕реВрдЪреА рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрддреНрд╡реЛрдВ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рддрдм рддрдХ рд╡рд╛рджреЗ рдкреВрд░реЗ рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ рдЬрдм рддрдХ рдХрд┐ рд╣рдорд╛рд░реА рдЬрд░реВрд░рдд рдкреВрд░реА рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддреАред рдПрдХ рд╡рд╛рджрд╛ рджреВрд╕рд░реЛрдВ рдХреЛ рдЬрдиреНрдо рджреЗ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рдЫреЛрдЯреА рд╕реВрдЪреА рдФрд░ рд╡рд╛рджреЗ рд╕реЗ, рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рдПрдХ рд╡рд┐рд╢рд╛рд▓ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рддрдВрддреБ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрдм рдЪрдХреНрд░реАрдп рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред

data List a = List {value :: a, next :: List a}

рд╣рдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рджреЛ рддрддреНрд╡реЛрдВ рдХреЛ рдПрдХ рдЕрдВрдЧреВрдареА рдореЗрдВ рдХреИрд╕реЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдПрдХ рд╡рд╕реНрддреБ рдХрд╛ рдЕрдЧрд▓рд╛ рдХреНрд╖реЗрддреНрд░ рджреВрд╕рд░реЗ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░реЗ?
рдпрджрд┐ рд╣рдо рдЗрд╕реЗ рдЕрдирд┐рд╡рд╛рд░реНрдп рднрд╛рд╖рд╛ рдореЗрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдХреЛрдИ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдирд╣реАрдВ рд╣реИрдВред рддреЛ рдРрд╕реА рд╕рдВрд░рдЪрдирд╛ рдХреИрд╕реЗ рдмрдирд╛рдПрдВ?
рдмрд╣реБрдд рд╕рд░рд▓:

let x = List "x" y
y = List "y" x
in x


рд╡рд╣ рд╕рдм рд╣реИред рдЪреВрдВрдХрд┐ рд╕реВрдЪреА рдЕрдЧрд▓рд╛ рдлрд╝реАрд▓реНрдб рдЖрд▓рд╕реА рд╣реИ (рд╣рдореЗрдВ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЯрд╛рдЗрдк рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдПрдХ рд╣реА рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рддрд░реНрдХ рдЖрд▓рд╕реА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ) рдЗрд╕ рддрд░рд╣ рдХреА "рд░рд┐рдВрдЧ" рдмрдирд╛рдиреЗ рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдкреВрд░реЗ рдврд╛рдВрдЪреЗ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рдпрд╛рд╕реЛрдВ рдореЗрдВ рдлрд╝реНрд░реАрдЬрд╝ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред

> value . next $ x
"y"


рдЖрд▓рд╕реА I / O

рдХреЗрд╡рд▓ рд╕рд░рд▓ I / O рдлрд╝рдВрдХреНрд╢рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдЦреНрдд рд╣реИрдВ, рдФрд░ рдмрд╛рдХреА рдЖрд▓рд╕реА рд╣реИрдВред рдпрд╣ рдордХреНрдЦреА рдкрд░ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдкрдврд╝рдирд╛ рдФрд░ рд▓рд┐рдЦрдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рдПрдХ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдкрд░, рдмрдлрд╝рд░реНрд╕ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд┐рдирд╛ред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

import Data.Char

main = print . map toUpper =<< getContents


рдХрд╛рд░реНрдпрдХреНрд░рдо рдКрдкрд░реА рдкрд╛рда рдореЗрдВ рдЖрддреЗ рд╣реА рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдЧрд╛ред

рдЖрд▓рд╕реА рдХрдореНрдкреНрдпреВрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдорд╕реНрдпрд╛рдПрдВ


рдкреВрд░реЗ рд▓реЗрдЦ рдХреЗ рджреМрд░рд╛рди, рдореИрдВрдиреЗ рдЖрд▓рд╕реА рдЕрднрд┐рдХрд▓рди рдХреА рдПрдХ рдЗрдХрд╛рдИ рдХрд╛ рдЕрд░реНрде "рд╡рд╛рджрд╛" рд╢рдмреНрдж рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдЕрдореВрд░реНрдд рдЕрд╡рдзрд╛рд░рдгрд╛ рдирд╣реАрдВ рд╣реИред рд╕рдВрдХрд▓рд┐рдд рд╣рд╛рд╕реНрдХреЗрд▓ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрди рд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕реНрдореГрддрд┐ рдореЗрдВ рдФрд░ рд╕реНрдЯреИрдХ рдкрд░ рдЬрдЧрд╣ рд▓реЗрддреЗ рд╣реИрдВред рдпрд╣реА рд╣реИ, рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣, рд╕реНрдореГрддрд┐ рдЖрд╡рдВрдЯрди, рдФрд░ рд╡рд╛рджреЛрдВ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЛ рдкрд╛рд░рдВрдкрд░рд┐рдХ рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреА рд▓рд╛рдЧрддреЛрдВ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЖрд▓рд╕реА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреА рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рд╣реИ - рдЙрдирдХреЗ рдЕрдирдкрдврд╝ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП, рдЖрдк рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рднрд╛рд░реА рдХрдореА, рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдФрд░ рдЙрдЪреНрдЪ рдореЗрдореЛрд░реА рдЦрдкрдд рдХреЗ рд╕рд╛рде рднреБрдЧрддрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд▓реЗрдХрд┐рди рдЧрдгрдирд╛ рдХреЛ рдХрдо рдЖрд▓рд╕реА рдмрдирд╛рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рдЕрдм рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВред

seq

рдЗрд╕ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

 main = print . sum' $ [1..1e6] sum' [] = 0 sum' (l:ls) = l + sum' ls 

рдпрд╣рд╛рдВ рд╣рдо 1 рд╕реЗ 1e6 рддрдХ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдпреЛрдЧ рдкрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдХрдВрд╕реЛрд▓ рдкрд░ рдкреНрд░рд┐рдВрдЯ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдХрд╛рд░реНрдпрдХреНрд░рдо рдЪрд▓рд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдпрд╣ рд╕рдВрджреЗрд╢ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

$ ./test
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.


рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдХреНрдпреЛрдВ рд╣реЛрддрд╛ рд╣реИ? рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд░рд╛рд╢рд┐ 'рдлрдВрдХреНрд╢рди рдХреА рдЧрдгрдирд╛ рдХреИрд╕реЗ рдХреА рдЬрд╛рдПрдЧреА:
1 + (1 + (1 + ... (1 + sum' [])))

рдЪреВрдБрдХрд┐ sum' ls рдХреА рдЧрдгрдирд╛ рдореЗрдВ рджреЗрд░реА рд╣реЛ рд░рд╣реА рд╣реИ, рд╣рдореЗрдВ рдвреЗрд░ рд╕рд╛рд░реЗ рдиреЗрд╕реНрдЯреЗрдб рд╡рд╛рджреЗ рдорд┐рд▓рддреЗ рд╣реИрдВ рдЬреЛ рд╕реНрдЯреИрдХ рдкрд░ рдЬрдЧрд╣ рд▓реЗрддреЗ рд╣реИрдВред рдЗрд╕рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА рддрд░рд╣ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХрд╛ рд╡рд╛рджрд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рд╕рдВрдЪрд┐рдд рдирд╣реАрдВред рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ seq рдлрд╝рдВрдХреНрд╢рди рд╣реИред рдЗрд╕рдореЗрдВ рджреЛ рддрд░реНрдХ рджрд┐рдП рдЧрдП рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкрд╣рд▓рд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рд╡рд╛рдкрд╕ рд▓реМрдЯрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕реЗ рдпрд╣рд╛рдВ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдкреВрдВрдЫ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╛рд╢рд┐ 'рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

 main = print . sum' $ [1..1e6] sum' ls = go 0 ls where go n [] = n go n (l:ls) = go (l + n) ls 

рдЕрдм рдЕрддрд┐рд░рд┐рдХреНрдд рдЧрдгрдирд╛ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реЛрдЧрд╛:

 main = print . sum' $ [1..1e6] sum' ls = go 0 ls where go n [] = n go n (l:ls) = let s = l + n in s `seq` go s ls 

Seq рдмрд╛рдж рдореЗрдВ рд╕реНрдердЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд░рд╛рд╢рд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░рддрд╛ рд╣реИред

$ ./test
5.000005e11


рдЕрдм рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред

рдЖрдЗрдП рдереЛрдбрд╝рд╛ рдЬрдЯрд┐рд▓ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ: рддрддреНрд╡реЛрдВ рдХреЗ рдпреЛрдЧ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЙрдирдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рднреА рдХрд░рддреЗ рд╣реИрдВред

 main = print . sum' $ [1..1e6] sum' ls = go (0, 0) ls where go (n, d) [] = (n, d) go (n, d) (l:ls) = let t = (l + n, d + 1) in t `seq` go t ls 

$ ./test
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.


рдлрд┐рд░ рд╕реЗ рд╡рд╣реА рдЧрд▓рддреАред рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВ? рдХреНрдпрд╛ рд╣рдордиреЗ рд░рд╛рд╢рд┐ рдХреА рдЧрдгрдирд╛ рдХреА?
рдпрд╣ seq рдХреА рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ: рдпрд╣ WHNF рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред рд╕рд╛рдзрд╛рд░рдг рд╕рдВрдЦреНрдпрд╛, рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, WHNF рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ seq рджреНрд╡рд╛рд░рд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЧрдгрдирд╛ рдХреА рдЧрдИ рдереАред рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдПрдХ рдЬреЛрдбрд╝реА рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ WHNF рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рд╣реИ (**, **) ред рдЗрд╕рд▓рд┐рдП рд╡рд╛рджреЗ рдЕрднреА рднреА рдвреЗрд░ рд╣реЛ рд░рд╣реЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рдЕрддрд┐рдкреНрд░рд╡рд╛рд╣ рд╣реИред рдЦреЗрддреЛрдВ рдХреЛ рдордЬрдмреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо seq рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 main = print . sum' $ [1..1e6] sum' ls = go (0, 0) ls where go (n, d) [] = (n, d) go (n, d) (l:ls) = let s = l + n d' = d + 1 in s `seq` d' `seq` go (s, d') ls 

$ ./test
(5.000005e11,1000000)


рдереЛрдбрд╝рд╛ рдмрджрд╕реВрд░рдд, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╕реНрдерд┐рддрд┐ рдЬрдм рдЖрдкрдХреЛ рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдпрд╣ рдмрд╣реБрдд рджреБрд░реНрд▓рдн рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЖрдЗрдП рдЗрд╕реЗ рдЖрдЬрдорд╛рдПрдБ:

 import Control.DeepSeq (deepseq) main = print . sum' $ [1..10^6] sum' :: [Integer] -> (Integer, Int) sum' ls = go (0, 0) ls where go (n, d) [] = (n, d) go (n, d) (l:ls) = let t = (l + n, d + 1) in t `deepseq` go t ls 

рдбреАрдкрд╕реЗрдХ рдлрд╝рдВрдХреНрд╢рди рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рддрдХ рдорд╛рдиреЛрдВ рдХреА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред

рдмреИрдВрдЧ рдкреИрдЯрд░реНрди

рдХрдареЛрд░рддрд╛ рдХреЗ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╕рдВрдХреЗрдд рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕рдВрдХрд▓рдХ рд╡рд┐рд╕реНрддрд╛рд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ - рдмреИрдВрдЧ рдкреИрдЯрд░реНрдиред рдпрд╣ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рд╡рд┐рд╕реНрдордпрд╛рджрд┐рдмреЛрдзрдХ рдмрд┐рдВрджреБ рджреНрд╡рд╛рд░рд╛ рддрд░реНрдХ рдХреА рдЧрдВрднреАрд░рддрд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдЗрд╕ рддрд░рд╣ рджреЛрдмрд╛рд░рд╛ рд▓рд┐рдЦ тАЛтАЛрд╕рдХрддреЗ рд╣реИрдВ:

 {-# LANGUAGE BangPatterns #-} main = print . sum' $ [1..10^6] sum' :: [Integer] -> (Integer, Int) sum' ls = go (0, 0) ls where go (!n, !d) [] = (n, d) go (!n, !d) (l:ls) = go (l + n, d + 1) ls 

рд╕рдм рдХреБрдЫ рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред
рдмреИрдВрдЧ рдкреИрдЯрд░реНрди рд╣рдореЗрдВ рди рдХреЗрд╡рд▓ рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХреЛрдВ рдХреА рдЧрдВрднреАрд░рддрд╛ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рднреА, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 {-# LANGUAGE BangPatterns #-} data SPair ab = SPair !a !b deriving Show main = print . sum' $ [1..10^6] sum' :: [Integer] -> SPair Integer Int sum' ls = go (SPair 0 0) ls where go (SPair nd) [] = SPair nd go (SPair nd) (l:ls) = go (SPair (l + n) (d + 1)) ls 

$ ./test
SPair 500000500000 1000000


SPair рдПрдХ рд╕рдЦреНрдд рдпреБрдЧрд▓ рд╣реИред рдЗрд╕рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреА рд╣рдореЗрд╢рд╛ рдЧрдгрдирд╛ рдХреА рдЬрд╛рдПрдЧреА, рдЬреЛ рдлрд┐рд░ рд╕реЗ, рд╡рд╛рджреЛрдВ рдХреЛ рдЬрдорд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖


рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВрдиреЗ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдХрд┐ рдЖрд▓рд╕реА рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХрд╛ рд╕рд╛рдордирд╛ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдпрд╣ рд╕рдордЭрдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдВрдЧреЗ рдХрд┐ рдЖрд╕реНрдердЧрд┐рдд рдЧрдгрдирд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛рдВ рдФрд░ рдХреИрд╕реЗ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рдкреНрд░рдпреБрдХреНрдд рд╕рд╛рдордЧреНрд░реА рдХреА рд╕реВрдЪреА


рд╣рд╛рд╕реНрдХреЗрд▓ / рдЖрд▓рд╕реНрдп
рд░реВрдкрд░реЗрдЦрд╛ рдФрд░ рдЕрдиреБрдХреВрд▓рди

Source: https://habr.com/ru/post/In131910/


All Articles