рдореЛрдиреЙрдпрдб рд╕реНрдЯреИрдХрд┐рдВрдЧ рдорд╢реАрди


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


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


рдпрд╣ рд▓реЗрдЦ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рд╣реИ рдЬреЛ рд╣рд╛рд╕реНрдХреЗрд▓ рднрд╛рд╖рд╛ рдХреЛ рдПрдХ рдордзреНрдпрд╡рд░реНрддреА рд╕реНрддрд░ рдкрд░ рдФрд░ рдЙрд╕рд╕реЗ рдКрдкрд░ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╛рдо рдпрд╛ рд╢реЛрдз рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЙрди рд╕рднреА рдЬрд┐рдЬреНрдЮрд╛рд╕реБрдУрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдПрдХ рдирдЬрд╝рд░ рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдХрд╛рд░реНрдп рдХрд░рдирд╛ рдмрд╛рдХреА рд╣реИред рдЦреИрд░, рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЬрд┐рдиреНрд╣реЗрдВ рдкрд┐рдЫрд▓реЗ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдиреЗ рдбрд░рд╛ рдирд╣реАрдВ рдерд╛ред


рдпрд╣ рдХреЛрдб рдореЗрдВ рдХрдИ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдмрд╣реБрдд рд╕рд╛рд░реА рд╕рд╛рдордЧреНрд░реА рдирд┐рдХрд▓рд╛, рдФрд░ рдкрд╛рдардХ рдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдЙрд╕реЗ рдЗрд╕рдореЗрдВ рдЧреЛрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдореИрдВ рдПрдиреЛрдЯреЗрдЯ рд╕рд╛рдордЧреНрд░реА рджреВрдВрдЧрд╛ред


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

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


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



рд╕реНрдЯреИрдХ рдорд╢реАрдиреЛрдВ рдХреЗ рд▓рд┐рдП рднрд╛рд╖рд╛ рдФрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо


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


рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╕реНрдЯреИрдХ рдХреИрд▓рдХреБрд▓реЗрдЯрд░
calc :: String -> [Int] calc = interpretor . lexer where lexer = words interpretor = foldl (flip interprete) [] interprete c = case c of "add" -> binary $ \(x:y:s) -> x + y:s "mul" -> binary $ \(x:y:s) -> x * y:s "sub" -> binary $ \(x:y:s) -> y - x:s "div" -> binary $ \(x:y:s) -> y `div` x:s "pop" -> unary $ \(x:s) -> s "dup" -> unary $ \(x:s) -> x:x:s x -> case readMaybe x of Just n -> \s -> n:s Nothing -> error $ "Error: unknown command " ++ c where unary fs = case s of x:_ -> fs _ -> error $ "Error: " ++ c ++ " expected an argument." binary fs = case s of x:y:_ -> fs _ -> error $ "Error: " ++ c ++ " expected two arguments." 

рдпрд╣ Text.Read рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдХреБрд▓ readMaybe рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рджреЛ рдЧреБрдирд╛ рдХрдо рддрдХ рд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдмрд┐рдирд╛ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢, рдЬреЛ рдмрджрд╕реВрд░рдд рд╣реИред


рдмрд╛рддрдЪреАрдд рдХреА рд╢рд╛рдирджрд╛рд░ рд╢реБрд░реБрдЖрдд! рдлрд┐рд░, рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рд╡реЗ рдкреНрд░рднрд╛рд╡ рдХреЛ рд╕рдВрд▓рдЧреНрди рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ: рд╡реЗ foldl рдХреЛ foldM рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП foldM , Either String foldM рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдордЧреНрд░рддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдлрд┐рд░ рд▓реЙрдЧрд┐рдВрдЧ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, WriterT рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рд▓рдкреЗрдЯрддреЗ рд╣реИрдВ, рдЪрд░ рдХреЗ рд▓рд┐рдП StateT рд╢рдмреНрджрдХреЛрд╢ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕реА рддрд░рд╣ред рдХрднреА-рдХрднреА, рд░рд╛рдХреНрд╖рд╕реА рдЧрдгрдирд╛рдУрдВ рдХреА рд╢реАрддрд▓рддрд╛ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡реЗ рдПрдХ рдЕрд╕реНрдкрд╖реНрдЯ рдХреИрд▓рдХреБрд▓реЗрдЯрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд╕рднреА рд╕рдВрднрд╛рд╡рд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИ ( 2 p m 3 ) тИЧ ( ( 4 p m 8 ) p m 5 )    ред рдпрд╣ рдПрдХ рд▓рдВрдмреА, рдЕрдЪреНрдЫреА рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рддрдЪреАрдд рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╣рдо рддреБрд░рдВрдд рдЕрдкрдиреА рдХрд╣рд╛рдиреА рдХреЛ рдПрдХ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдЖрдЧреЗ рдмрдврд╝рд╛рдПрдВрдЧреЗ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣рдо рдЗрд╕реЗ рдЙрд╕реА рдкрд░рд┐рдгрд╛рдо рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред


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


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


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


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


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


рдЬрдм рдмреЙрдиреНрдбрд┐рдВрдЧ, рдСрд░реНрдбрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпреЗ рджреЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдирд┐рд╕реНрд╕рдВрджреЗрд╣ рдЕрд▓рдЧ рд╣реИрдВ:

 рдЯреА рдИ рдПрдХреНрд╕ рдЯреА рдЯреА рдЯреА 5 рдб реБ рдм рдХ реА рдк реЙ рдк рдПрди рдИ рдХреНрдпреВ рдЯреА рдИ рдПрдХреНрд╕ рдЯреА рдЯреА рдЯреА 5 рдк реЙ рдк рдб реБ рдк ред  


рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ рдЖрдк рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдХрд╣рд╛рдВ рд╕реЗ рдХрд╛рдЯрддреЗ рд╣реИрдВ, рдЕрдЧрд░ рдЖрдк рддреБрд░рдВрдд рдЗрд╕реЗ рдЗрд╕ рд╕реНрдерд╛рди рдкрд░ рдЧреЛрдВрдж рджреЗрддреЗ рд╣реИрдВ:

( texttt5dup)+ textttpop= texttt5+( textttduppop)$


рдпрд╣ рд╕рд░рд▓ рддрдереНрдп рд╕рдорд╡рд░реНрддреА рдСрдкрд░реЗрд╢рди рдХреА рд╕рдВрдмрджреНрдзрддрд╛ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рд╕рдВрд░рдЪрдирд╛ рд▓реЗрддрд╛ рд╣реИ рдХрд┐ рд╕реНрдЯреИрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдПрдХ рдирдП рд╕реНрддрд░ рдкрд░ рдмрдирддреЗ рд╣реИрдВ , рд╣рдо рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдПрдХ рдЕрд░реНрдзрд╡реГрддреНрдд рд╣реИ ред

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


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


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


 class Semigroup a where (<>) :: a -> a -> a class Semigroup a => Monoid a where mempty :: a 


рдПрдХ рдХрд╛рд░ рдХрд╛ рдирд┐рд░реНрдорд╛рдг


рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рдкреНрд░рдореБрдЦ
 {-# LANGUAGE LambdaCase, GeneralizedNewtypeDeriving #-} import Data.Semigroup (Max(..),stimes) import Data.Monoid import Data.Vector ((//),(!),Vector) import qualified Data.Vector as V (replicate) 

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


рдЖрдЗрдП рдЖрднрд╛рд╕реА рдорд╢реАрди рдФрд░ рддреБрдЪреНрдЫ рд╕реЗрдЯрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░реЗрдВред


 type Stack = [Int] type Memory = Vector Int type Processor = VM -> VM memSize = 4 data VM = VM { stack :: Stack , status :: Maybe String , memory :: Memory } deriving Show emptyVM = VM mempty mempty (V.replicate memSize 0) setStack :: Stack -> Processor setStack x (VM _ sm) = VM xsm setStatus :: Maybe String -> Processor setStatus x (VM s _ m) = VM sxm setMemory :: Memory -> Processor setMemory x (VM s st _) = VM s st x 

рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдЕрд░реНрде рдХреЛ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯрд░реНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдкреНрд░реЛрд╕реЗрд╕рд░ (рдЯрд╛рдЗрдк Processor ) рд╕реЗ рд╣рдорд╛рд░рд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ VM -> VM ред


рдЕрдм рд╣рдо рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдорд░ рдореЛрдиреЛрдЗрдб рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рд▓рд┐рдП рд░реИрдкрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:


 newtype Action a = Action { runAction :: a -> a } instance Semigroup (Action a) where Action f <> Action g = Action (g . f) instance Monoid (Action a) where mempty = Action id newtype Program = Program { getProgram :: Action VM } deriving (Semigroup, Monoid) 

рд░реИрдкрд░ рдкреНрд░рдХрд╛рд░ рд╕рдВрдпреЛрдЬрди рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ: рдпреЗ рд░рдЪрдирд╛ рдХреЗ рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ (рдмрд╛рдПрдВ рд╕реЗ рджрд╛рдПрдВ) рдХреЗ рд╕рд╛рде рдПрдВрдбреЛрдореЛрд░реНрдлрд┐рдЬреНрдо рд╣реИрдВред рд░реИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ Program рдкреНрд░рдХрд╛рд░ Semigroup рдФрд░ Monoid рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред


рдХрд╛рд░реНрдпрдХреНрд░рдо рдирд┐рд╖реНрдкрд╛рджрдХ рддреБрдЪреНрдЫ рд╣реИ:


 run :: Program -> Processor run = runAction . getProgram exec :: Program -> VM exec prog = run prog emptyVM 

рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдЧрд▓рдд рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:


 err :: String -> Processor err = setStatus . Just $ "Error! " ++ m 

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


 program :: (Stack -> Processor) -> Program program f = Program . Action $ \vm -> case status vm of Nothing -> f (stack vm) vm _ -> vm programM :: ((Memory, Stack) -> Processor) -> Program programM f = Program . Action $ \vm -> case status vm of Nothing -> f (memory vm, stack vm) vm _ -> vm 

рдЕрдм рдЖрдк рд╕реНрдЯреИрдХ рдФрд░ рдореЗрдореЛрд░реА, рдкреВрд░реНрдгрд╛рдВрдХ рдЕрдВрдХрдЧрдгрд┐рдд, рдФрд░ рд╕рдорддреБрд▓реНрдпрддрд╛ рдФрд░ рдЖрджреЗрд╢ рд╕рдВрдмрдВрдзреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рднрд╛рд╖рд╛ рдХрдорд╛рдВрдб рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рд╕реНрдЯреИрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ
 pop = program $ \case x:s -> setStack s _ -> err "pop expected an argument." push x = program $ \s -> setStack (x:s) dup = program $ \case x:s -> setStack (x:x:s) _ -> err "dup expected an argument." swap = program $ \case x:y:s -> setStack (y:x:s) _ -> err "swap expected two arguments." exch = program $ \case x:y:s -> setStack (y:x:y:s) _ -> err "exch expected two arguments." 

рд╕реНрдореГрддрд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВ
 --       indexed if = programM $ if (i < 0 || i >= memSize) then const $ err $ "expected index in within 0 and " ++ show memSize else f put i = indexed i $ \case (m, x:s) -> setStack s . setMemory (m // [(i,x)]) _ -> err "put expected an argument" get i = indexed i $ \(m, s) -> setStack ((m ! i) : s) 

рдЕрдВрдХрдЧрдгрд┐рдд рд╕рдВрдЪрд╛рд▓рди рдФрд░ рд╕рдВрдмрдВрдз
 unary nf = program $ \case x:s -> setStack (fx:s) _ -> err $ "operation " ++ show n ++ " expected an argument" binary nf = program $ \case x:y:s -> setStack (fxy:s) _ -> err $ "operation " ++ show n ++ " expected two arguments" add = binary "add" (+) sub = binary "sub" (flip (-)) mul = binary "mul" (*) frac = binary "frac" (flip div) modulo = binary "modulo" (flip mod) neg = unary "neg" (\x -> -x) inc = unary "inc" (\x -> x+1) dec = unary "dec" (\x -> x-1) eq = binary "eq" (\x -> \y -> if (x == y) then 1 else 0) neq = binary "neq" (\x -> \y -> if (x /= y) then 1 else 0) lt = binary "lt" (\x -> \y -> if (x > y) then 1 else 0) gt = binary "gt" (\x -> \y -> if (x < y) then 1 else 0) 

рдЙрдЪрд┐рдд рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП, рдкрд░реНрдпрд╛рдкреНрдд рдмреНрд░рд╛рдВрдЪрд┐рдВрдЧ рдФрд░ рд▓реВрдк рдирд╣реАрдВ рд╣реИред рджрд░рдЕрд╕рд▓, рдПрдореНрдмреЗрдбреЗрдб рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП, рдХреЗрд╡рд▓ рдмреНрд░рд╛рдВрдЪрд┐рдВрдЧ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ, рдореЗрдЬрдмрд╛рди рднрд╛рд╖рд╛ (рд╣рд╛рд╕реНрдХреЗрд▓) рдореЗрдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реВрдк рдХрд╛ рдЖрдпреЛрдЬрди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЕрдкрдиреА рднрд╛рд╖рд╛ рдХреЛ рдЖрддреНрдордирд┐рд░реНрднрд░ рдмрдирд╛рдПрдВрдЧреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЗрд╕ рддрдереНрдп рдХрд╛ рд▓рд╛рдн рдЙрдард╛рддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдПрдХ рд╕реЗрдореАрдЧреНрд░реБрдк рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд░рд┐рдкреАрдЯрд┐рд╢рди рдХреЗ рдХреЙрдореНрдмрд┐рдиреЗрдЯрд░ рдХреЛ рдХрдИ рдмрд╛рд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╡рд╣ рдвреЗрд░ рд╕реЗ рджреЛрд╣рд░рд╛рд╡ рдХреА рд╕рдВрдЦреНрдпрд╛ рд▓реЗ рдЬрд╛рдПрдЧрд╛ред


рдмреНрд░рд╛рдВрдЪрд┐рдВрдЧ рдФрд░ рд▓реВрдкрд┐рдВрдЧ
 branch :: Program -> Program -> Program branch br1 br2 = program go where go (x:s) = proceed (if (x /= 0) then br1 else br2) s go _ = err "branch expected an argument." while :: Program -> Program -> Program while test body = program (const go) where go vm = let res = proceed test (stack vm) vm in case (stack res) of 0:s -> proceed mempty s res _:s -> go $ proceed body s res _ -> err "while expected an argument." vm rep :: Program -> Program rep body = program go where go (n:s) = proceed (stimes n body) s go _ = err "rep expected an argument." proceed :: Program -> Stack -> Processor proceed prog s = run prog . setStack s 

branch рдкреНрд░рдХрд╛рд░ рдФрд░ рдХрд╛рд░реНрдп while рд╕рдВрдХреЗрдд рдорд┐рд▓рддрд╛ рд╣реИ рдХрд┐ рдпреЗ рд╕реНрдЯреИрдВрдб-рдЕрд▓реЛрди рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЙрдореНрдмрд┐рдиреЗрдЯрд░: рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдИрдбреАрдПрд╕рдПрд▓ рдмрдирд╛рддреЗ рд╕рдордп рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рджреГрд╖реНрдЯрд┐рдХреЛрдгред рд╕рднреА stimes рд▓рд┐рдП stimes рдлрд╝рдВрдХреНрд╢рди stimes рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ; рдпрд╣ рддрддреНрд╡реЛрдВ рдХреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред


рдЕрдВрдд рдореЗрдВ, рд╣рдо рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓рд┐рдЦреЗрдВрдЧреЗред


рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдЙрджрд╛рд╣рд░рдг
 --   fact = dup <> push 2 <> lt <> branch (push 1) (dup <> dec <> fact) <> mul --   fact1 = push 1 <> swap <> while (dup <> push 1 <> gt) ( swap <> exch <> mul <> swap <> dec ) <> pop --     --    range = exch <> sub <> rep (dup <> inc) --    , --      fact2 = mconcat [ dec, push 2, swap, range, push 3, sub, rep mul] --      fact3 = dup <> put 0 <> dup <> dec <> rep (dec <> dup <> get 0 <> mul <> put 0) <> get 0 <> swap <> pop --      copy2 = exch <> exch --     --     gcd1 = while (copy2 <> neq) ( copy2 <> lt <> branch mempty (swap) <> exch <> sub ) <> pop --       pow = swap <> put 0 <> push 1 <> put 1 <> while (dup <> push 0 <> gt) ( dup <> push 2 <> modulo <> branch (dec <> get 0 <> dup <> get 1 <> mul <> put 1) (get 0) <> dup <> mul <> put 0 <> push 2 <> frac ) <> pop <> get 1 

рдпрд╣ рдХреЛрдб рдХреА 120 рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдФрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рдмрджрд▓ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдорд╢реАрди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рддреАрди рдХреЙрдореНрдмрд┐рдиреЗрдЯрд░ рдХреЗ рд╕рд╛рде 18 рдХрдорд╛рдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд▓рд┐рдд рд╣реЛрддрд╛ рд╣реИред рдЗрд╕реА рддрд░рд╣ рд╕реЗ рд╣рдорд╛рд░реА рдХрд╛рд░ рдХрд╛рдо рдХрд░рддреА рд╣реИред


 ╬╗> exec (push 6 <> fact) VM {stack = [720], status = Nothing, memory = [0,0,0,0]} ╬╗> exec (push 6 <> fact3) VM {stack = [720], status = Nothing, memory = [720,0,0,0]} ╬╗> exec (push 2 <> push 6 <> range) VM {stack = [6,5,4,3,2], status = Nothing, memory = [0,0,0,0]} ╬╗> exec (push 6 <> push 9 <> gcd1) VM {stack = [3], status = Nothing, memory = [0,0,0,0]} ╬╗> exec (push 3 <> push 15 <> pow) VM {stack = [14348907], status = Nothing, memory = [43046721,14348907,0,0]} ╬╗> exec (push 9 <> add) VM {stack = [9], status = Just "Error! add expected two arguments", memory = [0,0,0,0]} 

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


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



Monoids рдХрд╛ рдорд┐рд╢реНрд░рдг


рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╕рдордп рддрдХ рд╕рдВрд╢рдпрд╡рд╛рджрд┐рдпреЛрдВ рдФрд░ рдЖрдХрд╕реНрдорд┐рдХ рдкрд╛рдардХреЛрдВ рдиреЗ рд╣рдореЗрдВ рдкрд╣рд▓реЗ рд╣реА рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рд╣реИ, рдЖрдк рдЦреБрдж рдХреЛ рдЖрд░рд╛рдо рдХрд░рдиреЗ рдФрд░ рдЕрдореВрд░реНрдд рд╕реНрддрд░ рдкрд░ рдЬрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗ рд╕рдХрддреЗ рд╣реИрдВред


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


1) рдореЛрдиреЛрдЗрдбреНрд╕ рдФрд░ рд╕реВрдЬреАрдЧреНрд░реБрдкреНрд╕ рдХреЛ "рдЧреБрдгрд╛" рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдЙрддреНрдкрд╛рдж рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╣рд╛рд╕реНрдХреЗрд▓ рдХрд╛ рдЕрдореВрд░реНрдд рдПрдХ рдЯрдкрд▓ рдпрд╛ рдпреБрдЧреНрдо рд╣реИред


 instance (Semigroup a, Semigroup b) => Semigroup (a,b) where (a1, b1) <> (a2, b2) = (a1 <> a2, b1 <> b2) instance (Monoid a, Monoid b) => Monoid (a,b) where mempty = (mempty, mempty ) 

2) рдПрдХ рдПрдХрд▓ рдореЛрдиреЙрдЗрдб рд╣реИ, рдпрд╣ рдПрдХ рдПрдХрд▓ рдкреНрд░рдХрд╛рд░ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ () :


 instance Semigroup () where () <> () = () instance Monoid () where mempty = () 

рдЧреБрдгрди рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╕рд╛рде, рдЕрд░реНрдзрд╡реГрддреНрдд рд╕реНрд╡рдпрдВ рдПрдХ рдЕрд░реНрдзрд╡реГрддреНрдд рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЗрдХрд╛рдИ рдкреНрд░рдХрд╛рд░ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ monoids рдПрдХ monoid рдмрдирд╛рддреЗ рд╣реИрдВ! рдПрдХ рдЗрдХрд╛рдИ рдХреА рд╕рд╣рд╛рдиреБрднреВрддрд┐ рдФрд░ рддрдЯрд╕реНрдерддрд╛ isomorphism рддрдХ рдкреВрд░реА рд╣реЛ рдЬрд╛рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИред


3) рдПрдХ рдЕрд░реНрдзрд╡реГрддреНрдд рдпрд╛ рдореЛрдиреЛрдб рд░реВрдк рдореЗрдВ рдореИрдкрд┐рдВрдЧ, рдХреНрд░рдорд╢рдГ, рдПрдХ рд╕реЗрдореАрдЧреНрд░реБрдк рдпрд╛ рдореЛрдиреЛрдЗрдбред рдФрд░ рдпрд╣рд╛рдБ, рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдЗрд╕ рдХрдерди рдХреЛ рд▓рд┐рдЦрдирд╛ рднреА рдЖрд╕рд╛рди рд╣реИ:


 instance Semigroup a => Semigroup (r -> a) where f <> g = \r -> fr <> gr instance Monoid a => Monoid (r -> a) where mempty = const mempty 

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


 (command1 <> command2) r == command1 r <> command2 r 

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


рд╣рдо рдорд╢реАрди рдХреА рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдПрдХ рд▓реЙрдЧ рдХреЛ рдкреЗрд╢ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕реЗ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдирд╣реАрдВ рдмрд╛рдВрдзреЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХрд░реЗрдВрдЧреЗред рд╣рдо рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдореЛрдиреЛрдЗрдбрд▓ рдСрдкрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрддреНрд░рд┐рдХрд╛ рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗред


 data VM a = VM { stack :: Stack , status :: Maybe String , memory :: Memory , journal :: a } deriving Show mkVM = VM mempty mempty (V.replicate memSize 0) setStack x (VM _ st ml) = VM x st ml setStatus st (VM s _ ml) = VM s st ml setMemory m (VM s st _ l) = VM s st ml addRecord x (VM s st mj) = VM s st m (x<>j) newtype Program a = Program { getProgram :: Action (VM a) } deriving (Semigroup, Monoid) type Program' a = (VM a -> VM a) -> Program a 

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


рдирдП рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдФрд░ рдХреЙрдореНрдмрд┐рдиреЗрдЯрд░ред
 program fp = Program . Action $ \vm -> case status vm of Nothing -> p . (f (stack vm)) $ vm m -> vm programM fp = Program . Action $ \vm -> case status vm of Nothing -> p . (f (memory vm, stack vm)) $ vm m -> vm proceed p prog s = run (prog p) . setStack s rep body p = program go id where go (n:s) = proceed p (stimes n body) s go _ = err "rep expected an argument." branch br1 br2 p = program go id where go (x:s) = proceed p (if (x /= 0) then br1 else br2) s go _ = err "branch expected an argument." while test body p = program (const go) id where go vm = let res = proceed p test (stack vm) vm in case (stack res) of 0:s -> proceed p mempty s res _:s -> go $ proceed p body s res _ -> err "while expected an argument." vm 

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


 exec prog = run (prog id) (mkVM ()) 

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


 execLog p prog = run (prog $ \vm -> addRecord (p vm) vm) (mkVM mempty) 

рдЬрд╛рдирдХрд╛рд░реА рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬреИрд╕реЗ:


 logStack vm = [stack vm] logStackUsed = Max . length . stack logSteps = const (Sum 1) logMemoryUsed = Max . getSum . count . memory where count = foldMap (\x -> if x == 0 then 0 else 1) 

:


 ╬╗> exec (push 4 <> fact2) VM {stack = [24], status = Nothing, memory = [0,0,0,0], journal = ()} ╬╗> journal $ execLog logSteps (push 4 <> fact2) Sum {getSum = 14} ╬╗> mapM_ print $ reverse $ journal $ execLog logStack (push 4 <> fact2) [4] [3] [2,3] [3,2] [2,2] [3,2] [3,3,2] [4,3,2] [4,4,3,2] [5,4,3,2] [3,5,4,3,2] [2,4,3,2] [12,2] [24] 

, , . :


 f &&& g = \r -> (fr, gr) 


 ╬╗> let report p = journal $ execLog (logSteps &&& logStackUsed) p ╬╗> report (push 8 <> fact) (Sum {getSum = 48},Max {getMax = 10}) ╬╗> report (push 8 <> fact1) (Sum {getSum = 63},Max {getMax = 4}) ╬╗> report (push 8 <> fact2) (Sum {getSum = 26},Max {getMax = 9}) ╬╗> report (push 8 <> fact3) (Sum {getSum = 43},Max {getMax = 3}) 

&&& , . , Haskell . , .




. тАФ , Haskell. .


, , тАФ . , : . ( ) , ( ) . , , . - .


! :


 data Code = IF [Code] [Code] | REP [Code] | WHILE [Code] [Code] | PUT Int | GET Int | PUSH Int | POP | DUP | SWAP | EXCH | INC | DEC | NEG | ADD | MUL | SUB | DIV | EQL | LTH | GTH | NEQ deriving (Read, Show) 

тЖТ :


 fromCode :: [Code] -> Program' a fromCode = hom where hom = foldMap $ \case IF b1 b2 -> branch (hom b1) (hom b2) REP p -> rep (hom p) WHILE tb -> while (hom t) (hom b) PUT i -> put i GET i -> get i PUSH i -> push i POP -> pop DUP -> dup SWAP -> swap EXCH -> exch INC -> inc DEC -> dec ADD -> add MUL -> mul SUB -> sub DIV -> frac EQL -> eq LTH -> lt GTH -> gt NEQ -> neq NEG -> neg 

, . foldMap , . fromCode , , , c:


 ╬╗> stack $ exec (fromCode [PUSH 2, PUSH 5, EXCH, SUB, REP [DUP, INC]]) [5,4,3,2] ╬╗> stack $ exec (fromCode $ read "[PUSH 2, PUSH 5, EXCH, SUB, REP [DUP, INC]]") [5,4,3,2] 

тЖТ , case . : ! Program :


 newtype Program a = Program { getProgram :: ([Code], Action (VM a)) } deriving (Semigroup, Monoid) run = runAction . snd . getProgram 

run , fromCode :


 toCode :: Program' a -> [Code] toCode prog = fst . getProgram $ prog id 

, . , :


 type Program' a = (Code -> VM a -> VM a) -> Program a program cfp = Program . ([c],) . Action $ \vm -> case status vm of Nothing -> pc . f (stack vm) $ vm _ -> vm programM cfp = Program . ([c],) . Action $ \vm -> case status vm of Nothing -> pc . f (memory vm, stack vm) $ vm _ -> vm 

, , , . , -:


 none = const id exec prog = run (prog none) (mkVM ()) execLog p prog = run (prog $ \c -> \vm -> addRecord (pc vm) vm) (mkVM mempty) logStack _ vm = [stack vm] logStackUsed _ = Max . length . stack logSteps _ = const (Sum 1) --   logCode c _ = [c] logRun com vm = [pad 10 c ++ "| " ++ pad 20 s ++ "| " ++ m] where c = show com m = unwords $ show <$> toList (memory vm) s = unwords $ show <$> stack vm pad nx = take n (x ++ repeat ' ') debug :: Program' [String] -> String debug = unlines . reverse . journal . execLog logRun 

 pop = program POP $ \case x:s -> setStack s _ -> err "POP expected an argument." push x = program (PUSH x) $ \s -> setStack (x:s) dup = program DUP $ \case x:s -> setStack (x:x:s) _ -> err "DUP expected an argument." swap = program SWAP $ \case x:y:s -> setStack (y:x:s) _ -> err "SWAP expected two arguments." exch = program EXCH $ \case x:y:s -> setStack (y:x:y:s) _ -> err "EXCH expected two arguments." app1 cf = program c $ \case x:s -> setStack (fx:s) _ -> err $ "operation " ++ show c ++ " expected an argument" app2 cf = program c $ \case x:y:s -> setStack (fxy:s) _ -> err $ "operation " ++ show c ++ " expected two arguments" add = app2 ADD (+) sub = app2 SUB (flip (-)) mul = app2 MUL (*) frac = app2 DIV (flip div) neg = app1 NEG (\x -> -x) inc = app1 INC (\x -> x+1) dec = app1 DEC (\x -> x-1) eq = app2 EQL (\x -> \y -> if (x == y) then 1 else 0) neq = app2 NEQ (\x -> \y -> if (x /= y) then 1 else 0) lt = app2 LTH (\x -> \y -> if (x > y) then 1 else 0) gt = app2 GTH (\x -> \y -> if (x < y) then 1 else 0) proceed p prog s = run (prog p) . setStack s rep body p = program (REP (toCode body)) go none where go (n:s) = if n >= 0 then proceed p (stimes n body) s else err "REP expected positive argument." go _ = err "REP expected an argument." branch br1 br2 p = program (IF (toCode br1) (toCode br2)) go none where go (x:s) = proceed p (if (x /= 0) then br1 else br2) s go _ = err "IF expected an argument." while test body p = program (WHILE (toCode test) (toCode body)) (const go) none where go vm = let res = proceed p test (stack vm) vm in case (stack res) of 0:s -> proceed p mempty s res _:s -> go $ proceed p body s res _ -> err "WHILE expected an argument." vm put i = indexed (PUT i) i $ \case (m, x:s) -> setStack s . setMemory (m // [(i,x)]) _ -> err "PUT expected an argument" get i = indexed (GET i) i $ \(m, s) -> setStack ((m ! i) : s) indexed cif = programM c $ if (i < 0 || i >= memSize) then const $ err "index in [0,16]" else f 

, ! , .


-, :


 ╬╗> toCode fact1 [PUSH 1,SWAP,WHILE [DUP,PUSH 1,GTH] [SWAP,EXCH,MUL,SWAP,DEC],POP] 

EDSL, .


-, , toCode fromCode -.


 ╬╗> toCode $ fromCode [PUSH 5, PUSH 6, ADD] [PUSH 5, PUSH 6, ADD] ╬╗> exec (fromCode $ toCode (push 5 <> push 6 <> add)) VM {stack = [11], status = Nothing, memory = [0,0,0,0], journal = ()} 

, : , . ghci fact , , Ctrl+C . , toCode , .


, , , - :


 ╬╗> putStrLn $ debug (push 3 <> fact) PUSH 3 | 3 | 0 0 0 0 DUP | 3 3 | 0 0 0 0 PUSH 2 | 2 3 3 | 0 0 0 0 LTH | 0 3 | 0 0 0 0 DUP | 3 3 | 0 0 0 0 DEC | 2 3 | 0 0 0 0 DUP | 2 2 3 | 0 0 0 0 PUSH 2 | 2 2 2 3 | 0 0 0 0 LTH | 0 2 3 | 0 0 0 0 DUP | 2 2 3 | 0 0 0 0 DEC | 1 2 3 | 0 0 0 0 DUP | 1 1 2 3 | 0 0 0 0 PUSH 2 | 2 1 1 2 3 | 0 0 0 0 LTH | 1 1 2 3 | 0 0 0 0 PUSH 1 | 1 1 2 3 | 0 0 0 0 MUL | 1 2 3 | 0 0 0 0 MUL | 2 3 | 0 0 0 0 MUL | 6 | 0 0 0 0 



. . , , !


, . тАФ . , , .


, : , . , , . !


, , :


 listing :: Program' a -> String listing = unlines . hom 0 . toCode where hom n = foldMap f where f = \case IF b1 b2 -> ouput "IF" <> indent b1 <> ouput ":" <> indent b2 REP p -> ouput "REP" <> indent p WHILE tb -> ouput "WHILE" <> indent t <> indent b c -> ouput $ show c ouput x = [stimes n " " ++ x] indent = hom (n+1) 

: , , , .


:
 ╬╗> putStrLn . listing $ fact2 INC PUSH 1 SWAP EXCH SUB DUP PUSH 0 GTH IF REP DUP INC : NEG REP DUP DEC DEC DEC REP MUL ╬╗> putStrLn . listing $ gcd1 WHILE EXCH EXCH NEQ EXCH EXCH LTH IF : SWAP EXCH SUB POP 

. , , . .


, тАФ , . , . :

рдПрдХ рдЖрд░ рдореИрдВ рдЯреА y ( рдРрдб ) = 2 тЦ╣ 1


рдпрд╣рд╛рдБ рдХреБрдЫ рдЕрдиреНрдп рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреА рдорд╛рдиреНрдпрддрд╛рдПрдБ рд╣реИрдВ:

рдПрдХ рдЖрд░ рдореИрдВ рдЯреА y ( рдзрдХреНрдХрд╛ ) = 0 тЦ╣ 1рдПрдХ рдЖрд░ рдореИрдВ рдЯреА y ( рдкреЙрдк ) = 1 тЦ╣ 0рдПрдХ рдЖрд░ рдореИрдВ рдЯреА y ( Exch ) = 2 тЦ╣ 3


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

рдЬрдм рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рд╡реИрдзрддрд╛ рдЖрджреЗрд╢реЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╡реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЧреИрд░-рддреБрдЪреНрдЫ рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрдпреБрдХреНрдд рд╣реЛрддреЗ рд╣реИрдВ:

(i1тЦ╣o1)тЛД(i2тЦ╣o2)=(a+i1)тЦ╣(a+o1+o2тИТi2),a=max(0,i2тИТo1).


рдпрд╣ рдСрдкрд░реЗрд╢рди рд╕рд╛рд╣рдЪрд░реНрдп рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдПрдХ рддрдЯрд╕реНрде рддрддреНрд╡ рд╣реИ, рдЬреЛ рдХрд┐ рдореЛрдиреЛрдЗрдбреНрд╕ рдкрд░ рдПрдХ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдЖрд╢реНрдЪрд░реНрдп рдХреА рдмрд╛рдд рдирд╣реАрдВ рд╣реИред рдЗрд╕ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
 infix 7 :> data Arity = Int :> Int deriving (Show,Eq) instance Semigroup Arity where (i1 :> o1) <> (i2 :> o2) = let a = 0 `max` (i2 - o1) in (a + i1) :> (a + o1 + o2 - i2) instance Monoid Arity where mempty = 0:>0 

рдФрд░ рдлрд┐рд░ рдЖрдк рдПрдХ рд╕рдорд░реВрдкрддрд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 arity :: Program' a -> Arity arity = hom . toCode where hom = foldMap $ \case IF b1 b2 -> let i1 :> o1 = hom b1 i2 :> o2 = hom b2 in 1:>0 <> (i1 `max` i2):>(o1 `min` o2) REP p -> 1:>0 WHILE tb -> hom t <> 1:>0 PUT _ -> 1:>0 GET _ -> 0:>1 PUSH _ -> 0:>1 POP -> 1:>0 DUP -> 1:>2 SWAP -> 2:>2 EXCH -> 2:>3 INC -> 1:>1 DEC -> 1:>1 NEG -> 1:>1 _ -> 2:>1 

, , . , , .


( ):


 ╬╗> arity (exch <> exch) 2 :> 4 ╬╗> arity fact1 1 :> 1 ╬╗> arity range 2 :> 1 ╬╗> arity (push 3 <> dup <> pow) 0 :> 1 

? , "" . Program' a -> Max Int , . , , :


 memoryUse :: Program' a -> Max Int memoryUse = hom . toCode where hom = foldMap $ \case IF b1 b2 -> hom b1 <> hom b2 REP p -> hom p WHILE tb -> hom t <> hom b PUT i -> Max (i+1) GET i -> Max (i+1) _ -> 0 

 ╬╗> memoryUse fact1 Max {getMax = 0} ╬╗> memoryUse fact3 Max {getMax = 1} ╬╗> memoryUse pow Max {getMax = 2} 

. , .


, : , , , 0:>_ . . , .


 isReducible p = let p' = fromCode p in case arity p' of 0:>_ -> memoryUse p' == 0 _ -> False reducible = go [] . toCode where go res [] = reverse res go res (p:ps) = if isReducible [p] then let (a,b) = spanBy isReducible (p:ps) in go (a:res) b else go res ps --    Last,  , --     spanBy test l = case foldMap tst $ zip (inits l) (tails l) of Last Nothing -> ([],l) Last (Just x) -> x where tst x = Last $ if test (fst x) then Just x else Nothing --    Endo    --  intercalate  splitOn     -- Data.List  Data.List.Split reduce p = fromCode . process (reducible p) . toCode $ p where process = appEndo . foldMap (\x -> Endo $ x `replaceBy` shrink x) shrink = toCode . foldMap push . reverse . stack . exec . fromCode replaceBy xy = intercalate y . splitOn x 

рдПрдХ рд╕рд░рд▓ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:


 ╬╗> let p = push 6 <> fact1 <> swap <> push 5 <> dup <> push 14 <> gcd1 <> put 1 ╬╗> toCode $ p [PUSH 6,PUSH 1,SWAP,WHILE [DUP,PUSH 1,GTH] [SWAP,EXCH,MUL,SWAP,DEC],POP,SWAP,PUSH 5,DUP,PUSH 14,WHILE [EXCH,EXCH,NEQ] [EXCH,EXCH,LTH,IF [] [SWAP],EXCH,SUB],POP,PUT 1] ╬╗> toCode $ reduce p [PUSH 720,SWAP,PUSH 5,PUSH 1,PUT 1] ╬╗> execLog logSteps (push 8 <> p) VM {stack = [5,8,720], status = Nothing, memory = [0,1,0,0], journal = Sum {getSum = 107}} ╬╗> execLog logSteps (push 8 <> reduce p) VM {stack = [5,8,720], status = Nothing, memory = [0,1,0,0], journal = Sum {getSum = 6}} 

рдЕрдиреБрдХреВрд▓рди рдиреЗ рдЙрди рдкреНрд░реЛрдЧреНрд░рд╛рдореЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░ рджрд┐рдпрд╛ рд╣реИ, рдЬрд┐рдирдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ 107 рд╕реЗ 6 рддрдХ рд╣реИред


, , , , - ( ).




: , , , ..? ? , , !


m VM -> VM VM -> m VM , . : " тАФ , ?!" , VM -> m VM , , , . Haskell >=> " ". , Action ActionM , :


 newtype ActionM ma = ActionM { runActionM :: a -> ma } instance Monad m => Semigroup (ActionM ma) where ActionM f <> ActionM g = ActionM (f >=> g) instance Monad m => Monoid (ActionM ma) where mempty = ActionM return 

, , >=> . .


 {-# LANGUAGE LambdaCase, GeneralizedNewtypeDeriving, TupleSections #-} import Data.Monoid hiding ((<>)) import Data.Semigroup (Semigroup(..),stimes,Max(..)) import Data.Vector ((//),(!),Vector,toList) import qualified Data.Vector as V (replicate) import Control.Monad import Control.Monad.Identity type Stack = [Int] type Memory = Vector Int memSize = 4 data VM a = VM { stack :: Stack , status :: Maybe String , memory :: Memory , journal :: a } deriving Show mkVM = VM mempty mempty (V.replicate memSize 0) setStack x (VM _ st ml) = return $ VM x st ml setStatus st (VM s _ ml) = return $ VM s st ml setMemory m (VM s st _ l) = return $ VM s st ml addRecord x (VM s st ml) = VM s st m (x<>l) ------------------------------------------------------------ data Code = IF [Code] [Code] | REP [Code] | WHILE [Code] [Code] | PUT Int | GET Int | PUSH Int | POP | DUP | SWAP | EXCH | INC | DEC | NEG | ADD | MUL | SUB | DIV | MOD | EQL | LTH | GTH | NEQ | ASK | PRT | PRTS String | FORK [Code] [Code] deriving (Read, Show) newtype ActionM ma = ActionM {runActionM :: a -> ma} instance Monad m => Semigroup (ActionM ma) where ActionM f <> ActionM g = ActionM (f >=> g) instance Monad m => Monoid (ActionM ma) where ActionM f `mappend` ActionM g = ActionM (f >=> g) mempty = ActionM return newtype Program ma = Program { getProgram :: ([Code], ActionM m (VM a)) } deriving (Semigroup, Monoid) type Program' ma = (Code -> VM a -> m (VM a)) -> Program ma program cfp = Program . ([c],) . ActionM $ \vm -> case status vm of Nothing -> pc =<< f (stack vm) vm m -> return vm programM cfp = Program . ([c],) . ActionM $ \vm -> case status vm of Nothing -> pc =<< f (memory vm, stack vm) vm m -> return vm run :: Monad m => Program ma -> VM a -> m (VM a) run = runActionM . snd . getProgram toCode :: Monad m => Program' ma -> [Code] toCode prog = fst . getProgram $ prog none none :: Monad m => Code -> VM a -> m (VM a) none = const return --     exec :: Program' Identity () -> VM () exec = runIdentity . execM execM :: Monad m => Program' m () -> m (VM ()) execM prog = run (prog none) (mkVM ()) execLog p prog = run (prog $ \c -> \vm -> return $ addRecord (pc vm) vm) (mkVM mempty) f &&& g = \c -> \r -> (fcr, gcr) logStack _ vm = [stack vm] logStackUsed _ = Max . length . stack logSteps _ = const (Sum 1) logCode c _ = [c] logRun com vm = [pad 10 c ++ "| " ++ pad 20 s ++ "| " ++ m] where c = show com m = unwords $ show <$> toList (memory vm) s = unwords $ show <$> stack vm pad nx = take n (x ++ repeat ' ') debug p = unlines . reverse . journal <$> execLog logRun p ------------------------------------------------------------ pop,dup,swap,exch :: Monad m => Program' ma put,get,push :: Monad m => Int -> Program' ma add,mul,sub,frac,modulo,inc,dec,neg :: Monad m => Program' ma eq,neq,lt,gt :: Monad m => Program' ma err m = setStatus . Just $ "Error : " ++ m pop = program POP $ \case x:s -> setStack s _ -> err "pop expected an argument." push x = program (PUSH x) $ \s -> setStack (x:s) dup = program DUP $ \case x:s -> setStack (x:x:s) _ -> err "dup expected an argument." swap = program SWAP $ \case x:y:s -> setStack (y:x:s) _ -> err "swap expected two arguments." exch = program EXCH $ \case x:y:s -> setStack (y:x:y:s) _ -> err "expected two arguments." put i = indexed (PUT i) i $ \case (m, x:s) -> setStack s <=< setMemory (m // [(i,x)]) _ -> err "put expected an argument" get i = indexed (GET i) i $ \(m, s) -> setStack ((m ! i) : s) indexed cif = programM c $ if (i < 0 || i >= memSize) then const $ err "index in [0,16]" else f app1 cf = program c $ \case x:s -> setStack (fx:s) _ -> err $ "operation " ++ show c ++ " expected an argument" app2 cf = program c $ \case x:y:s -> setStack (fxy:s) _ -> err $ "operation " ++ show c ++ " expected two arguments" add = app2 ADD (+) sub = app2 SUB (flip (-)) mul = app2 MUL (*) frac = app2 DIV (flip div) modulo = app2 MOD (flip mod) neg = app1 NEG (\x -> -x) inc = app1 INC (\x -> x+1) dec = app1 DEC (\x -> x-1) eq = app2 EQL (\x -> \y -> if (x == y) then 1 else 0) neq = app2 NEQ (\x -> \y -> if (x /= y) then 1 else 0) lt = app2 LTH (\x -> \y -> if (x > y) then 1 else 0) gt = app2 GTH (\x -> \y -> if (x < y) then 1 else 0) proceed p prog s = run (prog p) <=< setStack s rep body p = program (REP (toCode body)) go none where go (n:s) = if n >= 0 then proceed p (stimes n body) s else err "rep expected positive argument." go _ = err "rep expected an argument." branch br1 br2 p = program (IF (toCode br1) (toCode br2)) go none where go (x:s) = proceed p (if (x /= 0) then br1 else br2) s go _ = err "branch expected an argument." while test body p = program (WHILE (toCode test) (toCode body)) (const go) none where go vm = do res <- proceed p test (stack vm) vm case (stack res) of 0:s -> proceed p mempty s res _:s -> go =<< proceed p body s res _ -> err "while expected an argument." vm ask :: Program' IO a ask = program ASK $ \case s -> \vm -> do x <- getLine setStack (read x:s) vm prt :: Program' IO a prt = program PRT $ \case x:s -> \vm -> print x >> return vm _ -> err "PRT expected an argument" prtS :: String -> Program' IO a prtS s = program (PRTS s) $ const $ \vm -> print s >> return vm fork :: Program' [] a -> Program' [] a -> Program' [] a fork br1 br2 p = program (FORK (toCode br1) (toCode br2)) (const go) none where go = run (br1 p) <> run (br2 p) ------------------------------------------------------------ fromCode :: Monad m => [Code] -> Program' ma fromCode = hom where hom = foldMap $ \case IF b1 b2 -> branch (hom b1) (hom b2) REP p -> rep (hom p) WHILE tb -> while (hom t) (hom b) PUT i -> put i GET i -> get i PUSH i -> push i POP -> pop DUP -> dup SWAP -> swap EXCH -> exch INC -> inc DEC -> dec ADD -> add MUL -> mul SUB -> sub DIV -> frac MOD -> modulo EQL -> eq LTH -> lt GTH -> gt NEQ -> neq NEG -> neg _ -> mempty fromCodeIO :: [Code] -> Program' IO a fromCodeIO = hom where hom = foldMap $ \case IF b1 b2 -> branch (hom b1) (hom b2) REP p -> rep (hom p) WHILE tb -> while (hom t) (hom b) ASK -> ask PRT -> ask PRTS s -> prtS s c -> fromCode [c] fromCodeList :: [Code] -> Program' [] a fromCodeList = hom where hom = foldMap $ \case IF b1 b2 -> branch (hom b1) (hom b2) REP p -> rep (hom p) WHILE tb -> while (hom t) (hom b) FORK b1 b2 -> fork (hom b1) (hom b2) c -> fromCode [c] 

: stdin .


 ask, prt :: Program' IO a ask = program ASK $ \case s -> \vm -> do x <- getLine setStack (read x:s) vm prt = program PRT $ \case x:s -> \vm -> print x >> return vm _ -> err "PRT expected an argument" prtS :: String -> Program' IO a prtS s = program (PRTS s) $ const $ \vm -> print s >> return vm 

- , :


 ioprog = prtS "input first number" <> ask <> prtS "input second number" <> ask <> rep (prt <> dup <> inc) <> prt 

 ╬╗> exec ioprog input first number 3 input second number 5 3 4 5 6 7 8 VM {stack = [8,7,6,5,4,3], status = Nothing, memory = [0,0,0,0], journal = ()} 

, :


 fork :: Program' [] a -> Program' [] a -> Program' [] a fork br1 br2 p = program (FORK (toCode br1) (toCode br2)) (const go) pure where go = run (br1 p) <> run (br2 p) 

: run VM -> m VM , тАФ , , [] , тАФ .


:


 ╬╗> stack <$> exec (push 5 <> push 3 <> add `fork` sub) [[8],[2]] ╬╗> stack <$> exec (push 5 <> push 3 `fork` dup <> push 2) [[2,3,5],[2,5,5]] 

: (2┬▒3)тИЧ((4┬▒8)┬▒5) :


 ╬╗> let pm = add `fork` sub ╬╗> stack <$> exec (push 2 <> push 3 <> push 4 <> push 8 <> pm <> push 5 <> pm <> pm <> mul) [[40],[-28],[20],[-8],[8],[4],[-12],[24]] 

:


 ╬╗> journal <$> execLog logSteps (push 8 <> fact `fork` fact1 `fork` fact2 `fork` fact3) [Sum {getSum = 48},Sum {getSum = 63},Sum {getSum = 34},Sum {getSum = 43}] 

, fork , , fork .


. . , /, , .


тИЧтИЧтИЧ


- ╬╝╬м╬│╬╝╬▒ . , , , . , , , Lego: , - . , , , .


Lego , , тАФ , , . , , . тАФ ! , . , - . ( -) , . тАФ ! "" , , , , . , , .




. - , . тАФ , . .

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


All Articles