рд╣рд╛рд╕реНрдХреЗрд▓ рдПрдкреНрд▓рд╛рдпрд╕рд┐рд╡ рдкрд░реНрд╕рд░реНрд╕


рдкреНрд░реЗрд░рдгрд╛


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


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


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


рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдХреЛ рдЕрдореВрд░реНрддрддрд╛ рдХреЗ рдбрд░ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдЙрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдП (рд╣рд╛рдБ, рдореБрдЭреЗ рдЕрднреА рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрднреА-рдХрднреА рд╕рд╛рдЗрдХрд┐рд▓ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдХреБрд╢рд▓ рд╣реЛрддрд╛ рд╣реИ)ред


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


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


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


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


рдХрдХреНрд╖рд╛рдПрдВ рдЯрд╛рдЗрдк рдХрд░реЗрдВ


рд╣рд╛рд╕реНрдХреЗрд▓ рдкреНрд░рдХрд╛рд░ рдХреА рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рд╕реА ++ рдФрд░ рдЕрдиреНрдп рд╡рд╕реНрддреБ-рдЙрдиреНрдореБрдЦ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдХрдХреНрд╖рд╛рдУрдВ рд╕реЗ рдХреЛрдИ рд▓реЗрдирд╛-рджреЗрдирд╛ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рд╣рдо OOP рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд╛рджреГрд╢реНрдп рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЯрд╛рдЗрдк рдХрдХреНрд╖рд╛рдПрдВ рдЕрдзрд┐рдХ рддрд░реАрдХреЛрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЕрдзрд┐рднрд╛рд░ рдХреА рддрд░рд╣ рд╣реЛрддреА рд╣реИрдВред


рдХрдХреНрд╖рд╛рдПрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреА рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдХрдХреНрд╖рд╛ рдореЗрдВ рдмрдирд╛рдиреЗ рд╡рд╛рд▓реА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рднреА рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рд╕рдорд╛рдирддрд╛ рдХреЗ рд▓рд┐рдП рддреБрд▓рдирд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдЯрд┐рд▓ рд▓реЛрдЧреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рдм рдХреБрдЫ рдЖрджреЗрд╢ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХрд╛рд░реНрдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдирд╣реАрдВ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдЬрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреА рд╢реНрд░реЗрдгреА рдХреА рддреБрд▓рдирд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдЙрд╕реЗ Eq рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЖрджреЗрд╢ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - Ord (рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдирд╣реАрдВ рд╣реЛрдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ)ред рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рдХреЗ рдХреНрдпрд╛ рдкреНрд░рд┐рдВрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрд╣ Show рдХреНрд▓рд╛рд╕ рдХрд╛ рд╣реИ, рдЗрд╕рдореЗрдВ "рд╡рд┐рдкрд░реАрдд" Read рдХреНрд▓рд╛рд╕ рд╣реИ, рдЬреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЛ рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдореЗрдВ рдХреИрд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред


рдорд╛рдирдХ рдкреНрд░рдХрд╛рд░ рдХреА рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП (рдЬреИрд╕реЗ рдХрд┐ Eq , Show , Read ...), рдЖрдк рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЯрд╛рдЗрдк рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж deriving рдХреАрд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рдирдХ рддрд░реАрдХреЗ рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ:


 data Point = Point { xCoord :: Float , yCoord :: Float } deriving (Eq, Show) 

рдЖрдк рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 class PrettyPrint a where pPrint :: a -> String 

рдпрд╣рд╛рдБ PrettyPrint рд╡рд░реНрдЧ рдХрд╛ рдирд╛рдо рд╣реИ, рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЪрд░ рд╣реИред where рдХреАрд╡рд░реНрдб рдХреЛ рддрдерд╛рдХрдерд┐рдд рд╡рд░реНрдЧ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рдмрд╛рдж, рдЕрд░реНрдерд╛рддреН рдРрд╕реЗ рдХрд╛рд░реНрдп рдЬреЛ рдЗрд╕ рд╡рд░реНрдЧ рд╕реЗ рдЯрд╛рдЗрдк рдХреА рд╡рд╕реНрддреБрдУрдВ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред


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


 instance PrettyPrint Point where pPrint (Point xy) = "(" ++ show x ++ ", " ++ show y ++ ")" 

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


 showVsPretty :: (Show a, PrettyPrint a) => a -> (String, String) showVsPretty x = (show x, pPrint x) 

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


 >>> showVsPretty (Point 2 3) ("Point {xCoord = 2.0, yCoord = 3.0}","(2.0, 3.0)") >>> showVsPretty "str" error: No instance for (PrettyPrint [Char]) arising from a use of 'showVsPretty' 

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


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


рдкрд╛рд░реНрд╕рд░ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдПрдХ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рддрддреНрд╡реЛрдВ (String, a) рдЙрдкрдпреБрдХреНрдд рд╣реИ, рдЬрд╣рд╛рдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЪрд░ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реВрдкрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред


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


 newtype Parser a = Parser { unParser :: String -> [(String, a)] } 

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


 parseString :: String -> Parser a -> Maybe a parseString s (Parser p) = case (ps) of [("", val)] -> Just val _ -> Nothing 

рд╕рд╛рдзрд╛рд░рдг рдкрд╛рд░реНрд╕рд░


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


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


 predP :: (Char -> Bool) -> Parser Char predP p = Parser f where f "" = [] f (c : cs) | pc = [(cs, c)] | otherwise = [] 

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


 charP :: Char -> Parser Char charP char = predP (\c -> c == char) 

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


 stringP :: String -> Parser String stringP s = Parser f where fs' | s == s' = [("", s)] | otherwise = [] 

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


 skip :: (Char -> Bool) -> Parser () skip p = Parser (\s -> [(dropWhile ps, ())]) 

рдЕрдЧрд▓реЗ рджреЛ рдкрд░рд╕рд░реНрд╕ рдПрдХ-рджреВрд╕рд░реЗ рд╕реЗ рдХрд╛рдлреА рдорд┐рд▓рддреЗ-рдЬреБрд▓рддреЗ рд╣реИрдВред рджреЛрдиреЛрдВ рдЗрдирдкреБрдЯ рд▓рд╛рдЗрди рдЙрдкрд╕рд░реНрдЧ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рддрднреА рдпрджрд┐ рд╕рдлрд▓ рдЗрд╕ рдЙрдкрд╕рд░реНрдЧ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рдПрдХ рдЦрд╛рд▓реА рдЯреНрдпреВрдкрд▓ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреНред рдЖрдк рдЗрдирдкреБрдЯ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдХрд┐рд╕реА рднреА рд▓рд╛рдЗрди рдХреЛ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди isPrefixOf рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬреЛ Data.List рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реЛрддрд╛ рд╣реИред


 prefixP :: String -> Parser String prefixP s = Parser f where f input = if s `isPrefixOf` input then [(drop (length s) input, s)] else [] skipString :: String -> Parser () skipString s = Parser f where f input = if s `isPrefixOf` input then [(drop (length s) input, ())] else [] 

рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рд╣рдо рдмрд╛рдж рдХреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдПрдХ рд╕рд░рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдХреЛрдб рджреЛрд╣рд░рд╛рд╡ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдПрдВрдЧреЗред


рдПрдХ рдордЬрд╝реЗрджрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░реНрд╕рд░


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


рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдХрдХреНрд╖рд╛ рдХреЛ fmap рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ; рдХрдХреНрд╖рд╛ рдореЗрдВ рдПрдХ fmap рд╡рд┐рдзрд┐ рд╣реЛрддреА рд╣реИ:


 class Functor f where fmap :: (a -> b) -> fa -> fb 

рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдореЗрдВ рддрд╛рд░ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдФрд░, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЯрд╛рдЗрдк b рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЯрд╛рдЗрдк b рдХреА рд╡рд╕реНрддреБрдУрдВ рдореЗрдВ рдХреИрд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред рдХреНрдпрд╛ рдпрд╣ рдХрд╣рдирд╛ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рддрдм рдЯрд╛рдЗрдк b рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╛рд░реНрд╕рд░ рд╣реИ?


рдпрджрд┐ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рд╣реЛрдВрдЧреЗ:


 (a -> b) -> Parser a -> Parser b 

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


 instance Functor Parser where fmap :: (a -> b) -> Parser a -> Parser b fmap f (Parser p1) = Parser p2 where p2 :: String -> [(String, b)] p2 s = convert (p1 s) convert :: [(String, a)] -> [(String, b)] convert results = map (\(s, val) -> (s, f val)) results 

fmap рдлрдВрдХреНрд╢рди рдХрд╛ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ fmap fx == f <$> x рдкрд░реНрдпрд╛рдпрд╡рд╛рдЪреА рд╢рдмреНрдж рд╣реИ: fmap fx == f <$> x ред


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


 (<$) :: Functor f => a -> fb -> fa ($>) :: Functor f => fa -> b -> fb 

рдЙрд╕ рдкрд╛рд░реНрд╕рд░ рдХреЛ рдпрд╛рдж рд░рдЦреЗрдВ рдЬреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░реЗрдЦрд╛ рдХреЛ skipString ( skipString )? рдЕрдм рдЖрдк рдЗрд╕реЗ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 skipString :: String -> Parser () skipString s = () <$ prefixP s 

рдкрд╛рд░реНрд╕рд░ рд╕рдВрдпреЛрдЬрди


рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ, рд╕рднреА рдлрд╝рдВрдХреНрд╢рди рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдХрд░реА рдЬрд╛рддреА рд╣реИрдВ рдФрд░ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реЛрддреА рд╣реИрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ n рддрд░реНрдХреЛрдВ рдХрд╛ рдПрдХ рдХрд╛рд░реНрдп рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рддрд░реНрдХ рдХрд╛ рдПрдХ рдХрд╛рд░реНрдп рд╣реИ, рдЬреЛ n-1 рддрд░реНрдХреЛрдВ рдХрд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓реМрдЯрд╛рддрд╛ рд╣реИ:


 cons :: Int -> [Int] -> [Int] cons = (:) cons1 :: [Int] -> [Int] cons1 = cons 1 --  cons   

рд╣рдо fmap рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд╛рд░реНрд╕рд░ рдХреЗ рдЕрдВрджрд░ рдХреБрдЫ рдорд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рддреАрди рддрд░реНрдХреЛрдВ рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдкреНрд░рдХрд╛рд░ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдВрдЧреЗ:


 f :: c -> a -> b p :: Parser c (fmap fp) :: Parser (a -> b) 

рдлрд╝рдВрдХреНрд╢рди рдкрд╛рд░реНрд╕рд░ рдирд┐рдХрд▓рд╛! рдмреЗрд╢рдХ, рдПрдХ рд╕реНрдерд┐рддрд┐ рд╕рдВрднрд╡ рд╣реИ рдЬрдм рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрдирдкреБрдЯ рд▓рд╛рдЗрди рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рдпрд╛ рдкрд╛рд░реНрд╕рд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Parser b Parser (a -> b) рдФрд░ Parser a рдкрд╛рд░реНрд╕рд░ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ:


 applyP :: Parser (a -> b) -> Parser a -> Parser b 

рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреНрд░рдХрд╛рд░ рдмрд╣реБрдд рдХреБрдЫ fmap рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдорд╛рди рд╣реИ, рдХреЗрд╡рд▓ рдлрд╝рдВрдХреНрд╢рди рд╣реА рдЬрд┐рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдХрдВрдЯреЗрдирд░ рдореЗрдВ рднреА рд╣реИред рдпрд╣ рдЗрд╕ рдмрд╛рдд рдХреА рд╕рд╣рдЬ рд╕рдордЭ рджреЗрддрд╛ рд╣реИ рдХрд┐ applyP рдлрдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди applyP рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП: рдХрдВрдЯреЗрдирд░ рд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ (рдкрд╣рд▓реЗ рдкрд╛рд░реНрд╕рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк), рдЙрди рдорд╛рдиреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдЬрд┐рдирдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рджреВрд╕рд░реЗ рдкрд╛рд░реНрд╕рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо), рдФрд░ "рдкреИрдХ" рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рдиреЛрдВ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░реЗрдВред рдХрдВрдЯреЗрдирд░ рдореЗрдВ (рдПрдХ рдирдпрд╛ рдкрд╛рд░реНрд╕рд░ рдмрдирд╛рдПрдВ)ред рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рд╣рдо рд╕реВрдЪреА рд╕рдордЭ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ:


 applyP :: Parser (a -> b) -> Parser a -> Parser b applyP (Parser p1) (Parser p2) = Parser f where fs = [ (sx, fx) | (sf, f) <- p1 s, -- p1     (sx, x) <- p2 sf] -- p2   ,     

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


 class Functor f => Applicative f where pure :: a -> fa (<*>) :: f (a -> b) -> fa -> fb instance Applicative Parser where pure x = Parser (\s -> [(s, x)]) pf <*> px = Parser (\s -> [ (sx, fx) | (sf, f) <- unParser pf $ s, (sx, x) <- unParser px $ sf]) 

applyP рдлрдВрдХреНрд╢рди Applicative рдХреНтАНрд▓рд╛рд╕ рд╕реЗ <*> рд╣реИред рдЗрд╕ рд╡рд░реНрдЧ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЖрд╡реЗрджрдХ рдлрдВрдХреНрд╢рдВрд╕ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред


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


 (*>) :: fa -> fb -> fb (<*) :: fa -> fb -> fa 

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


<$> рдФрд░ <*> рдорд┐рд▓рд╛рдХрд░, рдЖрдк рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдбрд┐рдЬрд╝рд╛рдЗрди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:


 data MyStructType = MyStruct { field1 :: Type1 , field2 :: Type2 , field3 :: Type3 } 

рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг MyStruct рднреА рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ Type1 -> Type2 -> Type3 -> MyStructType ред рдЖрдк рдХрд┐рд╕реА рдЕрдиреНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╣реА рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдкрд╛рд░реНрд╕рд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдВрд░рдЪрдирд╛ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ:


 parser1 :: Parser Type1 parser2 :: Parser Type2 parser3 :: Parser Type3 

fmap рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ fmap , рдЖрдк рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдЗрди рдкрд╛рд░реНрд╕рд░ рдореЗрдВ рд╕реЗ рдкрд╣рд▓реЗ MyStruct рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 parserStruct' :: Parser (Type2 -> Type3 -> MyStructType) parserStruct' = MyStruct <$> parser1 

рдЖрдЗрдП рдЙрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ рдЬреЛ рдЕрдм рдкрд╛рд░реНрд╕рд░ рдХреЗ "рдЕрдВрджрд░" рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА <*> рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:


 parserStruct'' :: Parser (Type3 -> MyStructType) parserStruct'' = parserStruct' <*> parser2 parserStruct :: Parser MyStructType parserStruct = parserStruct'' <*> parser3 

рдирддреАрдЬрддрди, рд╣рдореЗрдВ рдкреВрд░реА рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╛рд░реНрд╕рд░ рдорд┐рд▓рд╛ (рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдпрд╣рд╛рдВ рд╣рдо рдЗрд╕ рдзрд╛рд░рдгрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдореВрд▓ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдЗрд╕рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рд╣реИ)ред рдПрдХ рд╣реА рдХрд╛рдо рдПрдХ рд▓рд╛рдЗрди рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


 parserStruct :: Parser MyStructType parserStruct = MyStruct <$> parser1 <*> parser2 <*> parser3 

рдЗрд╕ рддрд░рд╣ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕рд╛рдордирд╛ рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред


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


 data Operand = IntOp Int | IdentOp String 

рдпрджрд┐ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреВрд░реНрдгрд╛рдВрдХ рдФрд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, C) рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдирд╛ рдЬрд╛рдирддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдСрдкрд░реЗрдВрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╛рд░реНрд╕рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдпрд╛ рджреВрд╕рд░реЗ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░ рд╕рдХреЗред рдпрд╣ рдкрд╛рд░реНрд╕рд░ рдЕрдиреНрдп рджреЛ рд╕реЗ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдкрд╛рд░реНрд╕рд░реНрд╕ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░ рд╕рдХрддреА рд╣реИ рддрд╛рдХрд┐ рдЙрдирдХреЗ рдХрд╛рдо рдХреЗ рдкрд░рд┐рдгрд╛рдо рд╕рдВрдпреБрдХреНрдд рд╣реЛрдВред рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдХ рд╕реВрдЪреА рд╣реИ, рдФрд░ рд╕реВрдЪрд┐рдпреЛрдВ рдХрд╛ рд╕рдВрдпреЛрдЬрди рдЙрдирдХрд╛ рд╕рдВрдпреЛрдЬрди рд╣реИред рд╣рдо рджреЛ рдкрд╛рд░реНрд╕рд░реНрд╕ рдХреЛ рдорд┐рд▓рд╛рдХрд░ altP рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:


 altP :: Parser a -> Parser a -> Parser a altP (Parser p1) (Parser p2) = Parser (\s -> p1 s ++ p2 s) 

рддрдм рдСрдкрд░реЗрдВрдб рдкрд╛рд░реНрд╕рд░ рдХреЛ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдпрд╣рд╛рдВ рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ parserInt рдФрд░ parserIdent рдкрд╣рд▓реЗ рд╕реЗ рдХрд╣реАрдВ рд╡рд░реНрдгрд┐рдд рд╣реИрдВ:


 parserOperand :: Parser Operand parserOperand = altP parserIntOp parserIdentOp where parserIntOp = IntOp <$> parserInt parserIdentOp = IdentOp <$> parserIdent 

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


 class Applicative f => Alternative f where empty :: fa (<|>) :: fa -> fa -> fa instance Alternative Parser where empty = Parser (const []) px <|> py = Parser (\s -> unParser px s ++ unParser py s) 

рдСрдкрд░реЗрд╢рди <|> рдХреЗрд╡рд▓ infix рд╕рдВрдХреЗрддрди рдореЗрдВ altP рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдЬреЛ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдХрдИ рдкрд╛рд░реНрд╕рд░реНрд╕ рдХреЛ рдорд┐рд▓рд╛рдХрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред


рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рд╕рднреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП, рджреЛ рдХрд╛рд░реНрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, some рдФрд░ many рдкреНрд░рдХрд╛рд░ рдХреЗ fa -> f [a] ред рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рджреВрд╕рд░реЗ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


 some v = (:) <$> v <*> many v many v = some v <|> pure [] 

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


рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ


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


  expr ::= constExpr | binOpExpr | negExpr const ::= int int ::= digit{digit} digit ::= '0' | ... | '9' binOpExpr ::= '(' expr ' ' binOp ' ' expr ')' binOp ::= '+' | '*' negExpr ::= '-' expr 

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


рд╕рд╣реА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд▓реЗрдЦрди рдХреЗ рдЙрджрд╛рд╣рд░рдг:


 "123" "-(10 + 42)" "(1 + ((2 + 3) * (4 + 5)))" 

рдЧрд▓рдд рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЗ рдЙрджрд╛рд╣рд░рдг:


 " 666 " "2 + 3" "(10 * 10)" 

рд╣рдо рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ (рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдФрд░ рдмрд╛рдЗрдирд░реА рдСрдкрд░реЗрд╢рди) рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ:


 data Expr = ConstExpr Int | BinaryExpr Expr Operator Expr | NegateExpr Expr data Operator = Add | Mul 

рдЖрдк рдкрд╛рд░реНрд╕ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ! рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рд╣реА рддреАрди рд╡рд┐рдХрд▓реНрдк рд╣реЛрддреЗ рд╣реИрдВред рддреЛ рд╣рдо рд▓рд┐рдЦрддреЗ рд╣реИрдВ:


 -- expr ::= constExpr | binOpExpr | negExpr exprParser :: Parser Expr exprParser = constParser <|> binParser <|> negParser 

рдПрдХ рд╕реНрдерд┐рд░рд╛рдВрдХ рдПрдХ рдкреВрд░реНрдгрд╛рдВрдХ рд╣реИред рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдореЗрдВ, рдпрд╣ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ "рд▓рд┐рдкрдЯреЗ" рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕реАрдзреЗ рдкреВрд░реНрдгрд╛рдВрдХ рдХреЗ рд▓рд┐рдП рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП fmap рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


 -- const ::= int constParser :: Parser Expr constParser = ConstExpr <$> intParser 

рдПрдХ рдкреВрд░реНрдгрд╛рдВрдХ, рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдЧреИрд░-рд░рд┐рдХреНрдд рдЕрдиреБрдХреНрд░рдо рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рдЕрдВрдХ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди predP рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ Data.Char рдореЙрдбреНрдпреВрд▓ рд╕реЗ Data.Char рдХреЛ Data.Char ред рдЕрдм, рдЕрдВрдХреЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╛рд░реНрд╕рд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ some ( many рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдЕрдВрдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП)ред рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдкрд╛рд░реНрд╕рд░ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╕рднреА рд╕рдВрднрд╡ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рджреЗрддрд╛ рд╣реИ, рдЬреЛ рд╕рдмрд╕реЗ рд▓рдВрдмреЗ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЗрдирдкреБрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧ "123ab" рд╣реИ, рддреЛ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рд╕реВрдЪреА рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реЛрдЧреА: [("ab", "123"), ("3ab", "12"), ("23ab", "1")] ред рд╣рдореЗрдВ рдЕрдВрдХреЛрдВ рдХреЗ рд╕рдмрд╕реЗ рд▓рдВрдмреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдФрд░ рдЗрд╕реЗ Int рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдкреВрд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:


 -- int ::= digit{digit} -- digit ::= '0' | ... | '9' intParser :: Parser Int intParser = Parser $ \s -> let res = unParser (some digitParser) s in case res of [] -> [] ((rest, i) : xs) -> [(rest, read i)] where digitParser = predP isDigit 

рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдЕрдЧрд▓рд╛ рддрд░реАрдХрд╛ рдПрдХ рдмрд╛рдЗрдирд░реА рдСрдкрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЙрджреНрдШрд╛рдЯрди рдмреНрд░реИрдХреЗрдЯ рдореЗрдВ рдкрд╣рд▓реЗ рдмреНрд░реИрдХреЗрдЯ, рдкрд╣рд▓рд╛ рдСрдкрд░реЗрдВрдб, рд╕реНрдкреЗрд╕, рдСрдкрд░реЗрд╢рди рд╕рд┐рдВрдмрд▓, рджреВрд╕рд░рд╛ рд╕реНрдкреЗрд╕, рджреВрд╕рд░рд╛ рдСрдкрд░реЗрдВрдб рдФрд░ рдХреНрд▓реЛрдЬрд┐рдВрдЧ рдмреНрд░реИрдХреЗрдЯ рд╢рд╛рдорд┐рд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкрд╛рддреНрд░реЛрдВ (рдХреЛрд╖реНрдардХ рдФрд░ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди) рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо charP рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред exprParser рднрд╛рд╡ рд╣реИрдВ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдкрд╛рд░реНрд╕рд░ ( exprParser ) рд╣реИред рдмрд╛рдЗрдирд░реА рдСрдкрд░реЗрд╢рди рдкреНрд░рддреАрдХ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╕рд╣рд╛рдпрдХ рдкрд╛рд░реНрд╕рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдкрд╛рд░реНрд╕рд░реНрд╕ рдХреЗ рдЗрд╕ рд╕реЗрдЯ рдХреЛ рдмрдбрд╝реЗ рдХрд░реАрдиреЗ рд╕реЗ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рддрд╛ рд╣реИред рд╢реБрд░реБрдЖрдд рдореЗрдВ рдФрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЕрдВрдд рдореЗрдВ рдХреЛрд╖реНрдардХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП: рдЖрдкрдХреЛ рдЗрд╕рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╕реНрд╡рдпрдВ рд╣реА рдЫреЛрдбрд╝ рджреЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, *> рдФрд░ <* рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:


 binParser :: Parser Expr binParser = charP '(' *> ??? <* charP ')' 

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


 BinaryExpr <$> exprParser --   <*> (charP ' ' *> binOpParser <* charP ' ') -- ,   <*> exprParser --   

рд╣рдо рдкреНрд░рд╢реНрдирд╡рд╛рдЪрдХ рдЪрд┐рдиреНрд╣ рдХреЗ рдмрдЬрд╛рдп рдЗрд╕ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:


 -- binOpExpr ::= '(' expr ' ' binOp ' ' expr ')' binParser :: Parser Expr binParser = charP '(' *> (BinaryExpr <$> exprParser <*> (charP ' ' *> binOpParser <* charP ' ') <*> exprParser ) <* charP ')' 

рдПрдХ рдмрд╛рдЗрдирд░реА рдСрдкрд░реЗрд╢рди рдпрд╛ рддреЛ + рд╡рд░реНрдг рд╣реИ рдЬреЛ Add рдорд╛рди рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИ, рдпрд╛ * рдЬреЛ Mul рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИ:


 -- binOp ::= '+' | '*' binOpParser :: Parser Operator binOpParser = plusParser <|> multParser where plusParser = charP '+' $> Add multParser = charP '*' $> Mul 

рд╡реНрдпрд╛рдХрд░рдг рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╣рд┐рд╕реНрд╕рд╛ рдХреНрдпрд╛ рд╣реИ, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдирд┐рд╖реЗрдзред рдПрдХ рдкреНрд░рддреАрдХ рдХреЗ рд╕рд╛рде - рдХреЛрд╖реНрдардХ рдФрд░ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рдХреЗ рд╕рд╛рде рднреА рдРрд╕рд╛ рд╣реА рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдмрд╛рдж, рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП NegateExpr рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:


 -- negExpr ::= '-' expr negParser = charP '-' *> (NegateExpr <$> exprParser) 

рддреЛ, рдкрд╛рд░реНрд╕рд░ рдХреЗ рд╕рднреА рднрд╛рдЧреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреЛрдб рдПрдХ рд╡реНрдпрд╛рдХрд░рдг рдХреА рддрд░рд╣ рд╣реИ рдФрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред


рд╕реНрд░реЛрдд рдХреЛрдб GitLab: https://gitlab.com/fierce-katie/applicative-parsers-demo рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред


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


 $ stack build $ stack exec demo-parser 

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


  • рд╡реНрдпрд╛рдХрд░рдг рдХреЛ рд╣рд░ рддрд░рд╣ рд╕реЗ рдмреЗрд╣рддрд░ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдЧреНрд░рдгреА рдФрд░ рд▓рдЯрдХрдиреЗ рд╡рд╛рд▓реЗ рд╕реНрдерд╛рдиреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рдирдП рдСрдкрд░реЗрд╢рдиреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдЖрджрд┐ред
  • рдкрд╛рд░реНрд╕рд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ рдФрд░ рджреБрднрд╛рд╖рд┐рдпрд╛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдкреНрд░рд┐рдВрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЧрдгрдирд╛ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред
  • attoparsec , attoparsec , optparse-applicative рдФрд░ optparse-applicative applicative-parsec рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ рдФрд░ optparse-applicative рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!


рдЙрдкрдпреЛрдЧреА рд╕рд╛рдордЧреНрд░реА


  1. Y рдорд┐рдирдЯ рдореЗрдВ рд╣рд╛рд╕реНрдХреЗрд▓ рд╕реАрдЦреЗрдВ
  2. рдбреЗрдирд┐рд╕ рд╢реЗрд╡рдЪреЗрдВрдХреЛред "рдПрдХ рдЗрдВрд╕рд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рд╣рд╛рд╕реНрдХреЗрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ"
  3. рдкрд╛рд░рд╕реЗрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп
  4. Attoparsec рдкреБрд╕реНрддрдХрд╛рд▓рдп
  5. рд▓рд╛рдЧреВ-рдкрд╛рд░рд╕реЗрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп
  6. рдСрдкреНрдЯрдкрд░реНрд╕-рдПрдкреЗрд░реЗрдЯрд┐рд╡ рд▓рд╛рдЗрдмреНрд░реЗрд░реА

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


All Articles