{"id":385926,"date":"2024-06-29T06:24:45","date_gmt":"2024-06-29T06:24:45","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=385926"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=385926","title":{"rendered":"<span>\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043d\u0430 Haskell + LLVM<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041d\u0430 \u0440\u0430\u0431\u043e\u0442\u0435 \u044f \u043f\u0438\u0448\u0443 \u043f\u043e\u0447\u0442\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430 Python, \u0441 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0441\u043a\u043e\u0439 \u0441\u043a\u0430\u043c\u044c\u0438 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f C\/C++, \u0432 \u043e\u0434\u043d\u043e\u043c pet-project \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b Haskell. \u0421 \u0442\u0430\u043a\u0438\u043c \u0431\u0430\u0433\u0430\u0436\u043e\u043c \u0437\u043d\u0430\u043d\u0438\u0439 \u044f \u0432\u0437\u044f\u043b\u0441\u044f \u0437\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 <strong>\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 LLVM<\/strong> &#8212; \u0437\u0430\u0447\u0435\u043c \u0438 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u044f \u0443\u0436\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0432 <a href=\"https:\/\/habr.com\/ru\/post\/508828\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>.<\/p>\n<p>\u042d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u044f \u043f\u0438\u0448\u0443 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u044f, \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d \u0432 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0438 Haskell, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438\u043b\u0438 \u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c\u0441\u044f \u0441 LLVM, \u043d\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u0441 \u043a\u0430\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u0446\u0430 \u043f\u043e\u0434\u043e\u0439\u0442\u0438 \u043a \u0437\u0430\u0434\u0430\u0447\u0435.<\/p>\n<p>\u042f \u043a\u0440\u0430\u0442\u043a\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 <strong>\u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0437\u043d\u0430\u043d\u0438\u0439 Haskell<\/strong>, \u043f\u0440\u043e \u0441\u0432\u043e\u0438 <strong>\u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u043a \u043a\u0430\u043a\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c \u044f \u043f\u0440\u0438\u0448\u0435\u043b<\/strong> &#8212; \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f \u0443\u0437\u043d\u0430\u043b \u043f\u043e\u0437\u0436\u0435 &#8212; \u0438 \u043a\u0430\u043a \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0432\u0430\u0448 pet-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440. \u041d\u0430 \u0432\u0441\u0451 \u044d\u0442\u043e \u044f \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u043c <strong>\u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435<\/strong>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1c1\/e91\/60f\/1c1e9160f3dec79f1fbc97f0765bf229.png\" width=\"1890\" height=\"850\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1c1\/e91\/60f\/1c1e9160f3dec79f1fbc97f0765bf229.png\"\/><figcaption><\/figcaption><\/figure>\n<hr\/>\n<h3>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/h3>\n<ol>\n<li>\n<p><a href=\"#part-1\" rel=\"noopener noreferrer nofollow\">Haskell &#8212; \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#part-2\" rel=\"noopener noreferrer nofollow\">\u041e\u0441\u043d\u043e\u0432\u044b \u044f\u0437\u044b\u043a\u0430 &#8212; \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u043f\u0430\u0440\u0441\u0435\u0440, AST<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#part-3\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0441 LLVM<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#part-4\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/a><\/p>\n<\/li>\n<\/ol>\n<blockquote>\n<p>\u041a\u043e\u0434 \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0440\u0430\u0437\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u043f\u043e \u0448\u0430\u0433\u0430\u043c: <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/VoidDruid\/habr-hs-llvm<\/a><\/p>\n<\/blockquote>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a &#171;\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0443\u0447\u0435\u0431\u043d\u0438\u043a&#187; \u0432 \u043f\u0430\u0440\u0435 \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u0435\u0439.<\/p>\n<p><a class=\"anchor\" name=\"part-1\" id=\"part-1\"><\/a><\/p>\n<h2>Haskell &#8212;  \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u0430 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h2>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0438\u0437 \u0432\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043a \u0441\u0442\u0430\u0442\u044c\u0435 &#8212; \u044f \u0432 haskell \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f &#8212; \u043d\u0435 \u043c\u0430\u0441\u0442\u0435\u0440-\u043a\u043b\u0430\u0441\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u0438 \u043d\u0435 \u0443\u0447\u0435\u0431\u043d\u0438\u043a \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u044f\u0437\u044b\u043a\u0443, \u0430 \u0441\u043a\u043e\u0440\u0435\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u043e\u0441\u043e\u0431\u0438\u0435 \u043d\u0430 \u0442\u0435\u043c\u0443 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u043e\u0434\u043e\u0439\u0442\u0438 \u043a \u0436\u0443\u0442\u043a\u043e \u0437\u0432\u0443\u0447\u0430\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 &#8212; \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435, \u0438 \u043d\u0435 \u043f\u043e\u0439\u0442\u0438 \u043d\u0430 \u0434\u043d\u043e \u0438\u0437-\u0437\u0430 &#171;\u043d\u0430\u0441\u043b\u043e\u0435\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438&#187;. \u0414\u0430\u043b\u0435\u0435 \u044f \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <a href=\"https:\/\/github.com\/VoidDruid\/grit\" rel=\"noopener noreferrer nofollow\">\u0441\u0432\u043e\u0435\u0439 \u0434\u0438\u043f\u043b\u043e\u043c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b<\/a>, \u0432\u044b\u043a\u0438\u043d\u0443\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0438\u0447\u0438, \u043d\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 (\u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440).<\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0433\u043e \u044f \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u043b\u0441\u044f \u0432 haskell, \u043d\u043e \u043a \u043d\u0430\u0447\u0430\u043b\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c \u044f \u0443\u0441\u043f\u0435\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u044d\u0442\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0442\u043e\u043b\u044c\u043a\u043e <a href=\"https:\/\/github.com\/VoidDruid\/telemonitor\" rel=\"noopener noreferrer nofollow\">telegram-\u0431\u043e\u0442\u0430<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043c\u043d\u0435 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0442\u044c \u043b\u0438\u0447\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440. \u0414\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u043e\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0436\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u043c\u0438 \u043f\u043e\u0437\u043d\u0430\u043d\u0438\u044f\u043c\u0438 \u0432 \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e, \u0447\u0442\u043e \u0432\u044b \u0437\u043d\u0430\u0435\u0442\u0435 (\u0445\u043e\u0442\u044f \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0438 \u043f\u043e \u0445\u043e\u0434\u0443):<\/p>\n<ul>\n<li>\n<p>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u044f\u0437\u044b\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0434\u0443\u043b\u0438 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u043a <em>\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c<\/em> \u0441 \u043c\u043e\u043d\u0430\u0434\u0430\u043c\u0438 (\u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043c\u0435\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0438), \u0445\u043e\u0442\u044f \u0431\u044b \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e<\/p>\n<\/li>\n<li>\n<p>do-\u043d\u043e\u0442\u0430\u0446\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>IO \u043c\u043e\u043d\u0430\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u043a\u0443\u0440\u0441\u0438\u044f, \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><em>\u0416\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e<\/em>: typeclasses, \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445, records<\/p>\n<\/li>\n<\/ul>\n<p>\u042f \u043f\u043e\u043f\u044b\u0442\u0430\u044e\u0441\u044c \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u0437\u0430\u0447\u0435\u043c \u0438 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u0430\u044f \u0444\u0438\u0447\u0430 \u044f\u0437\u044b\u043a\u0430, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0430\u044f \u0432 \u043f\u0443\u043d\u043a\u0442\u0435 &#171;<em>\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e<\/em>&#171;, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0449\u0435, \u0435\u0441\u043b\u0438 \u0432\u044b \u0441 \u043d\u0438\u043c\u0438 \u0437\u043d\u0430\u043a\u043e\u043c\u044b.<\/p>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e stack &#8212; \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e (<a href=\"https:\/\/docs.haskellstack.org\/en\/stable\/README\/#how-to-install\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f<\/a>), \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u0436\u0435. \u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u043d\u0443\u043b\u044f \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f &#8212; \u043c\u043e\u0436\u043d\u043e \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0442 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a>, \u0438 \u0438\u0434\u0442\u0438 \u0432 \u043d\u0435\u043c \u043f\u043e \u0448\u0430\u0433\u0430\u043c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u0435\u0439 (readme \u0435\u0441\u0442\u044c \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u043f\u043b\u044e\u0441 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 &#8212; \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u044c\u0442\u0435\u0441\u044c \u0441 \u043d\u0438\u043c\u0438, \u0447\u0442\u043e\u0431 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u0434\u0430). \u0418\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u0441\u0435 \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0432 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 &#8212; \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0430\u043c\u043e\u0433\u043e stack (<a href=\"https:\/\/docs.haskellstack.org\/en\/stable\/README\/#start-your-new-project\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f<\/a>) \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044d\u0442\u043e\u0442 <a href=\"https:\/\/github.com\/ProjectTemplates\/haskell-simple\" rel=\"noopener noreferrer nofollow\">\u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f cookiecutter<\/a>.<\/p>\n<blockquote>\n<p><a href=\"https:\/\/eax.me\/haskell-stack\/\" rel=\"noopener noreferrer nofollow\">\u041d\u0435\u043f\u043b\u043e\u0445\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f<\/a> \u0434\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445 \u043f\u0440\u043e stack \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c<\/p>\n<p>\u041a\u043d\u0438\u0433\u0430 \u043f\u0440\u043e haskell \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a <a href=\"http:\/\/learnyouahaskell.com\/chapters\" rel=\"noopener noreferrer nofollow\">\u043e\u043d\u043b\u0430\u0439\u043d-\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a<\/a>  <\/p>\n<\/blockquote>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 \u043a\u043e\u0434\u043e\u043c \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0441 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u043c \u0440\u0430\u0437\u0431\u043e\u0440\u043e\u043c, \u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u0439\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435, \u0437\u0430\u0439\u0434\u0438\u0442\u0435 \u0432 \u043f\u0430\u043f\u043a\u0443 <code>step-00<\/code>, \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 <code>stack run<\/code>. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441 \u0432\u0430\u043c\u0438 \u043f\u043e\u0437\u0434\u043e\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c, \u0442\u043e \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u0438\u0434\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>step-00<\/code>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 <code>\u0428\u0410\u0413 0<\/code>. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0448\u0430\u0433\u0443 (\u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043a \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0441 \u043a\u043e\u0434\u043e\u043c) \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a &#8212; <code>\u0428\u0410\u0413 \u0425<\/code>.<\/p>\n<p><a class=\"anchor\" name=\"part-2\" id=\"part-2\"><\/a><\/p>\n<h2>\u041e\u0441\u043d\u043e\u0432\u044b \u044f\u0437\u044b\u043a\u0430 &#8212; \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u043f\u0430\u0440\u0441\u0435\u0440, AST<\/h2>\n<h3>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0430\u0440\u0441\u0438\u043d\u0433<\/h3>\n<p><code>\u0428\u0410\u0413 1<\/code><\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c &#8212; \u044d\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0430\u0440\u0441\u0435\u0440. \u0412 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0445\u0430\u0441\u043a\u0435\u043b\u044f \u0435\u0441\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c <em>Parsec<\/em> (Parser Combinators &#8212; <a href=\"https:\/\/hackage.haskell.org\/package\/parsec\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/a>; <a href=\"https:\/\/www.stephendiehl.com\/llvm\/#chapter-2-parser-and-ast\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0443\u0447\u0438\u043b\u0441\u044f \u044f<\/a>), \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0432 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440\u044b. \u0414\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 <code>.cabal<\/code> \u0444\u0430\u0439\u043b \u0432 \u0441\u0435\u043a\u0446\u0438\u044e <code>build-depends<\/code>.<\/p>\n<blockquote>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/50337\/\" rel=\"noopener noreferrer nofollow\">\u0422\u0443\u0442\u043e\u0440\u0438\u0430\u043b<\/a> \u043f\u043e Parsec \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c<\/p>\n<\/blockquote>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435, \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0432\u0441\u0435 \u0435\u0449\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 <code>Main<\/code>. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432:<\/p>\n<pre><code class=\"haskell\">import Text.Parsec (parse) import Text.Parsec.String (Parser) import Text.Parsec.Language (emptyDef) import qualified Text.Parsec.Token as Tok<\/code><\/pre>\n<p>\u0427\u0442\u043e \u043c\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438:<\/p>\n<ul>\n<li>\n<p><code>parse<\/code> &#8212; \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u044e\u0449\u0430\u044f \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0430 \u0432\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p><code>Parser<\/code> &#8212; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u0433\u043e \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438<\/p>\n<\/li>\n<li>\n<p><code>emptyDef<\/code> &#8212; &#171;\u043f\u0443\u0441\u0442\u043e\u0435&#187; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u044f\u0437\u044b\u043a\u0430, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0432\u043e\u0435<\/p>\n<\/li>\n<li>\n<p><code>Text.Parsec.Token<\/code> &#8212; \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438-\u043f\u0430\u0440\u0441\u0435\u0440\u0430\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043b\u0435\u043a\u0441\u0435\u0440\u0430, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>makeTokenParser<\/code>, \u043f\u0435\u0440\u0435\u0434\u0430\u0432 \u0435\u0439 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0430:<\/p>\n<pre><code class=\"haskell\">lexer :: Tok.TokenParser () lexer = Tok.makeTokenParser style   where   ops = [ \"+\", \"*\", \"-\", \"\/\"]   names = [\"if\", \"else\"]   style = emptyDef {   Tok.commentLine = \"\/\/\"   , Tok.commentStart = \"\/*\"   , Tok.commentEnd = \"*\/\"   , Tok.caseSensitive = True   , Tok.reservedOpNames = ops   , Tok.reservedNames = names   }<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 <code>record<\/code> \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>style<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u043d\u0430\u0448\u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043a\u0440\u0430\u0439\u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e &#8212; \u0441\u0438-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438, \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 (<code>+<\/code>, <code>-<\/code>, <code>*<\/code>, <code>\/<\/code>) \u0438 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 <code>if<\/code> \u0438 <code>else<\/code>. \u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u043b\u0435\u043a\u0441\u0435\u0440 \u043c\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c <a href=\"https:\/\/hackage.haskell.org\/package\/parsec-3.1.14.0\/docs\/Text-Parsec-Token.html#t:GenTokenParser\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432<\/a> \u0438\u0437 <code>Tok<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0430:<\/p>\n<pre><code class=\"haskell\">integer    = Tok.integer lexer float      = Tok.float lexer -- \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 - https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-01\/app\/Main.hs<\/code><\/pre>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0446\u0435\u043b\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043c\u043e\u043d\u0430\u0434\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b, \u0438 \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430, \u0442\u043e \u0432\u0438\u0434\u043d\u043e \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438 \u043c\u043e\u043d\u0430\u0434\u0430\u043c\u0438, state-\u0430\u043c\u0438 \u0438 \u0442.\u0434. \u041a\u043e\u0433\u0434\u0430 \u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 Parsec, \u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u043b, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b do-\u043d\u043e\u0442\u0430\u0446\u0438\u044e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0430\u043a \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430\u0445. \u0412\u044b\u0448\u0435 \u044f \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e, \u0442\u0430\u043c \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0447\u0442\u043e <code>ParserT<\/code> \u044d\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u043e\u043d\u0430\u0434\u043d\u044b\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u043a\u0443\u0447\u0430 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 \u043c\u043e\u043d\u0430\u0434\u043d\u044b\u0445 \u0442\u0430\u0439\u043f \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e. \u0414\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0446\u0435\u043b\u0435\u0439 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u0430\u043c\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0430 \u043f\u0430\u0440\u0441\u0435\u0440-\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u043e\u0434\u043d\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u043d\u043e\u0432\u044b\u0435.<\/p>\n<p>\u0417\u043d\u0430\u044f \u044d\u0442\u043e, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u0438\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"haskell\">sumParse :: Parser Integer sumParse = do   first &lt;- integer   reservedOp \"+\"   second &lt;- integer   return (first + second)  runSumParse = parse sumParse \"&lt;stdin>\"<\/code><\/pre>\n<p>\u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u0437 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e-\u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443 \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e, \u0442\u0438\u043f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 <code>Parser \u0427\u0442\u043e\u0423\u0433\u043e\u0434\u043d\u043e<\/code>. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>sumParse<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443, \u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 \u0435\u0435 \u043a\u0430\u043a \u0431\u044b \u043f\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0449\u0435\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 do-\u0431\u043b\u043e\u043a\u0435:<\/p>\n<ul>\n<li>\n<p>\u0411\u0435\u0440\u0435\u0442 \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e <code>first &lt;- integer<\/code><\/p>\n<\/li>\n<li>\n<p>\u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 &#171;+&#187;<\/p>\n<\/li>\n<li>\n<p>\u0411\u0435\u0440\u0435\u0442 \u0432\u0442\u043e\u0440\u043e\u0435 \u0447\u0438\u0441\u043b\u043e <code>second &lt;- integer<\/code><\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f <code>return (first + second)<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u0423 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>runSumParse<\/code> \u043e\u0434\u0438\u043d \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 &#8212; \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043d\u0430 \u0440\u0430\u0437\u0431\u043e\u0440 <code>sumParse<\/code>. <code>\"&lt;stdin>\"<\/code> &#8212;  \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u043d\u0430 &#171;\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a&#187; \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043e\u0439\u0442\u0438 \u0432 ghci (\u043a\u043e\u043c\u0430\u043d\u0434\u0430 <code>stack ghci<\/code>), \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c <code>runSumParse \"1 + 2\"<\/code> &#8212;  \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f <code>Right 3<\/code>. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0447\u0442\u043e \u043d\u0430\u0448 \u043f\u0430\u0440\u0441\u0435\u0440 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a, \u0438 \u0432\u0435\u0440\u043d\u0443\u043b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <code>3<\/code> &#8212; \u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>parse<\/code> \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>Either ParseError a<\/code> &#8212; \u0433\u0434\u0435 <code>a<\/code> &#8212; \u0442\u0438\u043f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 <code>sumParse<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c <code>Integer<\/code>.<\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0434\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0442\u044b \u043f\u043e\u0434 \u044d\u0442\u0438\u043c \u044d\u0442\u0430\u043f\u043e\u043c, \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main<\/code> \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0447\u0438\u0442\u0430\u043b\u0430 \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u0438, \u043f\u0430\u0440\u0441\u0438\u043b\u0430 \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u043b\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<pre><code class=\"haskell\">main = do   line &lt;- getLine   case runSumParse line of   Right result -> putStrLn (\"Result: \" ++ show result)   Left error -> print error<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0423\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u0435 &#8212; \u043f\u0430\u0440\u0441\u0435\u0440 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430 &#8216;1++&#8217;. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0434 \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u043e\u043c<\/summary>\n<div class=\"spoiler__content\">\n<p> \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e &#171;++&#187; \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439: <code>ops = [ \"++\", \"+\", \"*\", \"-\", \"\/\"]<\/code>. \u0417\u0430\u0442\u0435\u043c \u043f\u0438\u0448\u0435\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440:<\/p>\n<pre><code class=\"haskell\">incrParse = do first &lt;- integer   reservedOp \"++\"   return (first + 1)<\/code><\/pre>\n<\/div>\n<\/details>\n<h3>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 AST<\/h3>\n<p><code>\u0428\u0410\u0413 2<\/code><\/p>\n<p>\u041e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u044d\u0442\u0430\u043f\u043e\u0432 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u044f\u0437\u044b\u043a\u0430, \u043f\u043e-\u043c\u043e\u0435\u043c\u0443 \u043e\u043f\u044b\u0442\u0443 &#8212; \u044d\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D0%BE%D0%B5_%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE\" rel=\"noopener noreferrer nofollow\">\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430<\/a>. \u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0443\u0442 \u0437\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0445\u0430\u0441\u043a\u0435\u043b\u0435\u043c, \u043e\u043f\u0438\u0441\u0430\u0442\u044c &#171;\u043e\u0431\u044b\u0447\u043d\u043e\u0435&#187; \u0434\u0435\u0440\u0435\u0432\u043e \u043b\u0435\u0433\u043a\u043e &#8212; \u044d\u0442\u043e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<pre><code class=\"haskell\">data Tree a = Leaf  -- \u0442\u0443\u043f\u0438\u043a | Node a (Tree a) (Tree a)  -- \u0443\u0437\u0435\u043b \u0434\u0435\u0440\u0435\u0432\u0430 - \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0434\u0432\u0435 \"\u044f\u0447\u0435\u0439\u043a\u0438\" \u043f\u043e\u0434 \u0432\u0435\u0442\u043a\u0438 deriving Show<\/code><\/pre>\n<p>\u0422\u0443\u0442 <code>Leaf<\/code> \u0438 <code>Node<\/code> &#8212; \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u0430 <code>Tree a<\/code>, \u0433\u0434\u0435 <code>a<\/code> &#8212; \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0443\u0437\u043b\u044b \u0434\u0435\u0440\u0435\u0432\u0430. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0448\u0435\u043c \u044f\u0437\u044b\u043a\u0435 (\u0435\u0449\u0435 \u0440\u0430\u0437 \u043d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u0445\u043e\u0442\u044c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0438 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0421\u0438, \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u043d\u0435 \u0441\u0438\u0448\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e &#171;\u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e&#187; \u0441\u0438-\u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430):<\/p>\n<pre><code class=\"haskell\">data Expr   = Int Integer  -- \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 Integer   | Var Name  -- \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439   | Def ExprType Name  -- \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439   | Block (CodeBlock Expr)  -- \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430   | Call String [Expr]  -- \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438   | Function ExprType Name [Expr] (Maybe Name) (CodeBlock Expr)  -- \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0434\u0430\u043b\u0435\u0435)   | BinaryOp String Expr Expr  -- \u0431\u0438\u043d\u0430\u0440\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0430\u0434 \u0434\u0432\u0443\u043c\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438   | If Expr (CodeBlock Expr) (CodeBlock Expr)  -- if - \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438 \u0434\u0432\u0435 \u0432\u0435\u0442\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f   deriving (Eq, Ord, Show)<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u0438\u043b\u0438 \u0441\u0430\u043c\u044b\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 (\u0441\u043c. \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0432 \u043a\u043e\u0434\u0435). \u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0434\u043e\u043f\u043e\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; <code>ExprType<\/code>, <code>CodeBlock<\/code>. \u041f\u0435\u0440\u0432\u044b\u0439 &#8212; \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e &#171;enum&#187; \u0441 \u0442\u0438\u043f\u0430\u043c\u0438, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439. \u0421\u0435\u0439\u0447\u0430\u0441 \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u044b \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0437\u0430\u0434\u0435\u043b \u043d\u0430 \u0431\u0443\u0434\u0443\u0449\u0435\u0435 \u0438 \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445:<\/p>\n<pre><code class=\"haskell\">data ExprType   = VoidType   | IntType   | FloatType   | BytesType   | BooleanType   | CallableType [ExprType] ExprType  -- [\u0442\u0438\u043f\u044b \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432] \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f   | AutoType  -- \u0442\u0438\u043f \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0432\u044b\u0432\u0435\u0434\u0435\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438   deriving (Eq, Ord)<\/code><\/pre>\n<p><code>CodeBlock<\/code> &#8212; \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u043a:<\/p>\n<pre><code class=\"haskell\">type CodeBlock term = [term] -- [expr1, expr2] \u044d\u0442\u043e CodeBlock Expr<\/code><\/pre>\n<p>\u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u043c\u0435\u0436\u0434\u0443 \u0442\u0438\u043f\u0430\u043c\u0438 <code>[Expr]<\/code> \u0438 <code>CodeBlock Expr<\/code> \u0447\u0438\u0441\u0442\u043e \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u0430\u044f &#8212; <code>CodeBlock<\/code> \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0442\u0430\u043c, \u0433\u0434\u0435 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u0442\u0435\u043b\u043e\u043c&#187; \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e (\u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0446\u0438\u043a\u043b\u0430 \u0438 \u043f\u0440.), \u0430 <code>[Expr]<\/code> &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043a \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0414\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0436\u0435 &#171;\u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e&#187; \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0442\u0438\u043f <code>AST<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445:<\/p>\n<pre><code class=\"haskell\">type AST = [Expr]<\/code><\/pre>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 <code>CodeBlock<\/code>, <code>AST<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u0441\u0442\u0440\u043e\u0433\u043e \u0434\u043b\u044f <code>Expr<\/code> . \u041c\u043d\u0435 \u044d\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043d\u0438\u0445 &#171;\u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442&#187; \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0435\u0441\u043b\u0438 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044e \u044d\u0442\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0438\u0437\u043b\u0438\u0448\u043d\u0438\u043c \u043d\u0430\u0433\u0440\u043e\u043c\u043e\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u043e\u0432, \u043e\u0442 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0435\u0437\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>[Expr]<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0440\u0443\u0447\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0435 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0437\u0430\u0441\u0443\u043d\u0443\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 &#8212; \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u0442\u0438\u043f\u043e\u0432 \u0432\u0441\u0435\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 (\u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b \u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u0434\u0430\u043b\u0435\u0435), \u0438 \u0434\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u043e\u043c\u0435\u0440\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0438\u0441\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f &#8212; \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445.<\/p>\n<p>\u042f \u043e\u0441\u043e\u0437\u043d\u0430\u043b \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u043e\u0437\u0434\u043d\u043e, \u0438 \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u044b\u0432\u0430\u0442\u044c, \u0431\u043b\u0430\u0433\u043e \u0434\u043b\u044f \u043c\u043e\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043c\u043d\u0435 \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u043e\u0441\u044c, \u043d\u043e \u0432 \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u0434\u043b\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 &#171;\u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0439\u043d\u044b\u0445&#187; \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434 &#171;Recursion Schemes&#187;. \u0412\u043e\u0442 <a href=\"https:\/\/blog.sumtypeofway.com\/posts\/introduction-to-recursion-schemes.html\" rel=\"noopener noreferrer nofollow\">\u043d\u0435\u043f\u043b\u043e\u0445\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u043e \u043d\u0435\u0433\u043e<\/a> &#8212; \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u043e\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u044f \u0434\u0435\u043b\u0430\u044e \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e, \u043e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0437\u043d\u0430\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u044b \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u0442\u0435\u0441\u044c \u043d\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 &#171;\u0441\u0435\u0440\u044c\u0435\u0437\u043d\u043e\u0433\u043e&#187; \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430, \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435, \u043f\u0440\u043e \u0447\u0442\u043e \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u044e \u0432 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435, \u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0434\u0440\u0438\u0442\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u0441\u0445\u0435\u043c\u044b.<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u044f\u0437\u044b\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0439-\u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432. \u041f\u043e\u043a\u0430 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438, \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0447\u0442\u043e \u0432\u044b\u0434\u0430\u0435\u0442 \u043f\u0430\u0440\u0441\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u044b\u0432\u0430\u044f \u0434\u0435\u0440\u0435\u0432\u043e <code>Expr<\/code>. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c\u0441\u044f \u043d\u0430 <code>derive Show<\/code>, \u0442\u043e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u0430\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0435\u043d\u0430 \u0442\u0435\u043a\u0441\u0442\u0430, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0438\u043d\u0441\u0442\u0430\u043d\u0441 Show \u0442\u0430\u043a\u043e\u0439, \u0447\u0442\u043e\u0431 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<p>\u041a\u043e\u0434\u0430 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 \u043c\u043d\u043e\u0433\u043e, \u0432\u0435\u0441\u044c \u0435\u0433\u043e \u044f \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443, \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435, \u043a\u0430\u043a \u0432\u0441\u0435\u0433\u0434\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-02\/app\/Syntax.hs\" rel=\"noopener noreferrer nofollow\">\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430<\/a>.<\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c <code>Show<\/code> \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"haskell\">instance Show ExprType where show VoidType = \"void\" show IntType = \"int\" -- \u0438 \u0442.\u0434.<\/code><\/pre>\n<p>\u0413\u043e\u0440\u0430\u0437\u0434\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u0435\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0434\u043b\u044f Expr. \u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u044f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e Show \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0439 <code>If<\/code> \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a, \u0447\u0442\u043e \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f <code>Show<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u0442\u0430\u0439\u043f \u043a\u043b\u0430\u0441\u0441:<\/p>\n<pre><code class=\"haskell\">{-  \u0442\u0430\u0439\u043f \u043a\u043b\u0430\u0441\u0441 Pretty \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e prettify, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0443\u044e \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u0442\u0440\u043e\u043a - \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \"\u043a\u0440\u0430\u0441\u0438\u0432\u0430\u044f\" \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u043a\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u043e\u0434\u043d\u0443 -} class Show e => Pretty e where prettify :: e -> [String]<\/code><\/pre>\n<p>\u042f \u0445\u043e\u0442\u0435\u043b \u0438\u043c\u0435\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>prettifyAST<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f \u043c\u043e\u0433 \u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c <code>AST<\/code> (\u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439) \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a &#8212; \u0434\u0430\u043b\u044c\u0448\u0435 \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0447\u0430\u0442\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0438\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0432 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b (<code>intercalate \"\\n\"<\/code> &#8212; \u043a\u0430\u0436\u0434\u044b\u0439 <code>String<\/code> \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435). \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b \u044f \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"haskell\">joinN = intercalate \"\\n\"  prettifyAST :: Pretty e => [e] -> [String] prettifyAST = map (joinN . prettify)  joinedPrettyAST :: Pretty e => [e] -> String joinedPrettyAST = joinN . prettifyAST<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0435\u043b\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 <code>Pretty Expr<\/code>. \u041a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b \u044f, \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-02\/app\/Syntax.hs#L77\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a> (\u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-02\/app\/StringUtils.hs\" rel=\"noopener noreferrer nofollow\">StringUtils<\/a>), \u043e\u0431\u0449\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0442\u0430\u043a\u0430\u044f:<\/p>\n<pre><code class=\"haskell\">instance Pretty Expr where   prettify expr = case expr of     (Int i) -> [joinS [\"Int\", show i]]     -- \u0438 \u0442\u0430\u043a \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e Expr<\/code><\/pre>\n<h3>\u041f\u0430\u0440\u0441\u0438\u043d\u0433<\/h3>\n<p>\u0412\u0441\u0435 \u0435\u0449\u0435 <code>\u0428\u0410\u0413 2<\/code><\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u0435\u043a\u0441\u0435\u0440, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432 \u0448\u0430\u0433\u0435 1. \u0414\u043b\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c <code>Parser<\/code> (<code>parser.hs<\/code>) \u0438 \u0432\u044b\u043d\u0435\u0441 \u0432\u0441\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0435 \u0441 \u043b\u0435\u043a\u0441\u0435\u0440\u043e\u043c \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u0432 \u043c\u043e\u0434\u0443\u043b\u044c <code>Lexer<\/code> (<code>lexer.hs<\/code>). \u0422\u0443\u0442 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u043e\u0432\u043e\u0433\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u043e\u0432 \u043f\u0430\u0440\u0441\u0435\u0440-\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0443\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b.<\/p>\n<p>\u0412\u043e\u0442 \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c (\u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u0438\u0445 \u044f \u043e\u043f\u0443\u0441\u043a\u0430\u044e):<\/p>\n<pre><code class=\"haskell\">import qualified Text.Parsec.Expr as Ex import qualified Text.Parsec.Token as Tok  import Lexer import Syntax<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0438 \u0441\u0430\u043c\u0430\u044f \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c &#8212; \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u0415\u0451 \u044f \u0432\u044b\u043d\u0435\u0441 \u043f\u043e\u0434 \u0441\u043f\u043e\u0439\u043b\u0435\u0440, \u043a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e &#8212; \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043f\u0430\u0440\u0441\u0435\u0440\u0430\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u044f \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043f\u043e\u0434 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435\u043c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>\u041a\u0430\u043a \u0432\u0441\u0435\u0433\u0434\u0430, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f (\u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u044d\u0442\u0430\u043f\u0430) <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-02\/app\/Parser.hs\" rel=\"noopener noreferrer nofollow\">\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0430\u0440\u0441\u0435\u0440\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0432\u0438\u0434\u0430 &#187; <code>+<\/code> &#171;, &#187; <code>*<\/code> &#187; \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435:<\/p>\n<pre><code class=\"haskell\">op :: Parser String op = do   whitespace   o &lt;- operator   whitespace   return o<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b <code>op<\/code> \u044d\u0442\u043e <code>String<\/code> \u0434\u043b\u044f \u0441\u0442\u0443\u043a\u0442\u0443\u0440\u044b<\/p>\n<pre><code class=\"haskell\">data Expr =   -- ...   BinaryOp String Expr Expr  -- \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0441 \u0434\u0432\u0443\u043c\u044f \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430\u043c\u0438<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b, \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u0438\u0445 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442:<\/p>\n<pre><code class=\"haskell\">{- binary - \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0432\u0435\u0440\u043d\u0435\u0442 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 BinaryOp (\u0431\u0435\u0437 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u0432 \u0442\u0438\u043f\u0430 Expr \u0438 Expr) \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0430\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 (s) \u0438 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c (\u0443 \u043d\u0430\u0441 - Ex.AssocLeft) -} binary s assoc = Ex.Infix (reservedOp s >> return (BinaryOp s)) assoc  -- \u0424\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\u044e \u0434\u043b\u044f \u0441\u043f\u0438\u0441\u043e\u043a\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 opList arity = opList' where      opList' [op] = [arity op Ex.AssocLeft]     opList' (op:ops) = arity op Ex.AssocLeft : opList' ops  binList = opList binary  -- \u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b (\u0442\u043e\u0447\u043d\u0435\u0435 \u0443\u0436\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0434\u043b\u044f \u043d\u0438\u0445 - \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f binList), \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0443\u0431\u044b\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430 binops = [   binList [\"*\", \"\/\", \"\/\/\", \"%\"]   , binList [\"+\", \"-\"]   , binList [\"&lt;\", \"=\", \"&lt;=\", \">=\", \"==\", \"!=\"] ]<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u044a\u044f\u0432\u0438\u043c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f &#8212; \u043e\u043d\u0430 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u0440\u0443\u0433\u0438\u0445:<\/p>\n<pre><code class=\"haskell\">{- \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0438\u044f \u043f\u0430\u0440\u0441\u0435\u043a\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f-\u043f\u0430\u0440\u0441\u0435\u0440, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f\u0449\u0430\u044f Expr. factor - \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0434\u0430\u043b\u0435\u0435, \u043e\u043d\u0430 \u043f\u0430\u0440\u0441\u0438\u0442 \"\u043e\u0431\u044b\u0447\u043d\u044b\u0435\" Expr binops - \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 (+, *, &lt;, != \u0438 \u043f\u0440.), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 Expr (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 - BinaryOp) -} expr :: Parser Expr expr =  Ex.buildExpressionParser binops factor<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>factor<\/code> &#8212; \u044d\u0442\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 <code>Expr<\/code>. \u041e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/hackage.haskell.org\/package\/parsec-3.1.14.0\/docs\/Text-Parsec-Prim.html#v:try\" rel=\"noopener noreferrer nofollow\">try<\/a>, \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"haskell\">factor :: Parser Expr factor = try cast       &lt;|> try block       &lt;|> try function       -- \u0438 \u0442.\u0434.<\/code><\/pre>\n<p>\u0423\u0436\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c \u043d\u0430\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0443\u0442\u0438\u043b\u0438\u0442\u0430\u0440\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u043e\u043d\u0430 \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0441\u0430\u043c\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"haskell\">-- \u043f\u0430\u0440\u0441\u0438\u0442 \u0432\u0441\u0435 \u0434\u043e eof \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 contents :: Parser a -> Parser a contents p = do   Tok.whiteSpace lexer   r &lt;- p   eof   return r  -- \u043f\u0430\u0440\u0441\u0438\u0442 \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 - \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438) toplevel :: Parser [Expr] toplevel = many $ do   def &lt;- function   reservedOp \";\"   return def  -- \u043f\u0430\u0440\u0441\u0438\u0442 \u043e\u0434\u043d\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 parseExpr :: String -> Either ParseError Expr parseExpr s = parse (contents expr) \"&lt;stdin>\" s  -- \u043f\u0430\u0440\u0441\u0438\u0442 \u043c\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 (\u0444\u0430\u0439\u043b \u0441 \u043a\u043e\u0434\u043e\u043c) parseCode :: String -> Either ParseError AST parseCode s = parse (contents toplevel) \"&lt;stdin>\" s<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0417\u0434\u0435\u0441\u044c \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 &#8212; \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 &#8212; \u043f\u0430\u0440\u0441\u0435\u0440 \u0438\u043d\u0442\u043e\u0432. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>integer<\/code> \u043c\u044b \u0434\u043e\u0441\u0442\u0430\u0435\u043c \u0438\u0437 \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u0447\u0438\u0441\u043b\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c <code>Expr<\/code>\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 <code>Int<\/code>:<\/p>\n<pre><code class=\"haskell\">int :: Parser Expr int = Int &lt;$> integer<\/code><\/pre>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432, \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u044f \u0438\u0445 \u0441 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0430\u043c\u0438:<\/p>\n<pre><code class=\"haskell\">codeBlock :: Parser [Expr] codeBlock = braces $ many $   do e &lt;- expr   reserved \";\"   return e<\/code><\/pre>\n<p>\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0432 \u0432\u0441\u0435 \u0432\u043c\u0435\u0441\u0442\u0435, \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440:<\/p>\n<pre><code class=\"haskell\">ifelse :: Parser Expr ifelse = do   reserved \"if\"  -- \u0438\u0449\u0435\u043c \u0432 \u043f\u043e\u0442\u043e\u043a\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e if   cond &lt;- parens expr  -- \u0437\u0430\u0442\u0435\u043c \u043b\u044e\u0431\u043e\u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0435 \u0432 \u043a\u0440\u0443\u0433\u043b\u044b\u0435 \u0441\u043a\u043e\u0431\u043a\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435   tr &lt;- codeBlock  -- \u043f\u0430\u0440\u0441\u0438\u043c codeBlock, \u044d\u0442\u043e true-\u0432\u0435\u0442\u043a\u0430 \u0438\u0444\u0430   fl &lt;- optionMaybe $ do  -- \u0432\u0435\u0442\u043a\u0430 else \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f, \u043f\u043e\u044d\u0442\u043e\u043c maybe \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0439\u0442\u0438 \"else\" \u0438 \u0435\u0449\u0435 \u043e\u0434\u0438\u043d codeBlock     reserved \"else\"     code &lt;- codeBlock     return code   return $ If cond tr (fromMaybe [] fl)  -- \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u0443\u0435\u043c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c Expr<\/code><\/pre>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c. \u041f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c <code>main<\/code> \u0442\u0430\u043a, \u0447\u0442\u043e\u0431 \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u043b \u043d\u0430 \u0432\u0445\u043e\u0434 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430, \u0438 \u043f\u0435\u0447\u0430\u0442\u0430\u043b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043a\u043e\u0434\u0430 \u0432 \u043d\u0435\u043c. \u0418\u043c\u043f\u043e\u0440\u0442\u044b \u044f \u043e\u043f\u0443\u0441\u043a\u0430\u044e, \u0430 \u0441\u0430\u043c <code>main<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"haskell\">main = do   args &lt;- getArgs  -- \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438   case args of     []   -> putStrLn \"Provide file name!\"     [filename] -> do  -- \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442       code &lt;- readFile filename  -- \u0447\u0438\u0442\u0430\u0435\u043c \u0444\u0430\u0439\u043b       case parseCode code of  -- \u0438 \u043f\u0430\u0440\u0441\u0438\u043c \u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435         Left err -> print err         -- \u0435\u0441\u043b\u0438 \u0443\u0441\u043f\u0435\u0445 - \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0430\u0448\u0443 joinedPrettyAST \u0447\u0442\u043e\u0431 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0447\u0438\u0442\u0430\u0435\u043c\u044b\u043c         Right ast -> putStrLn (joinedPrettyAST ast)       _ -> putStrLn \"Provide one file name!\"<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-02\/app\/Main.hs\" rel=\"noopener noreferrer nofollow\">main.hs<\/a> \u0438 <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-02\/main.grt\" rel=\"noopener noreferrer nofollow\">main.grt<\/a> (\u0444\u0430\u0439\u043b \u0441 \u043a\u043e\u0434\u043e\u043c) \u0443 \u043c\u0435\u043d\u044f (\u0438 \u0443 \u0432\u0430\u0441, \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0434\u0435\u0442\u0435 \u043f\u043e \u0448\u0430\u0433\u0430\u043c). \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <\/p>\n<pre><code class=\"bash\">stack run -- main.grt<\/code><\/pre>\n<p>\u0438 \u043f\u043e\u043b\u044e\u0431\u0443\u0435\u043c\u0441\u044f \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043d\u0430\u0448\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b &#8212; \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u043e\u0435 AST.<\/p>\n<details class=\"spoiler\">\n<summary>\u0422\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 AST<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>Function \"main\" int ; args [] ; returns Nothing {   BinaryOp = (Def int \"i\") (Int 0)   If (BinaryOp &lt; (Var \"i\") (Int 1)) {     Int 0   }   else {     Int 1   } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435 &#8212; \u043a \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<h3>\u0422\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044f<\/h3>\n<p><code>\u0428\u0410\u0413 3<\/code><\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430, \u043d\u0430\u0441\u0442\u0430\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0435\u0439. \u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432, \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0431\u044b \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0443\u0437\u043b\u0435 \u0434\u0435\u0440\u0435\u0432\u0430 \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u0442\u0438\u043f\u0430 <code>ExprType<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0432\u0435\u043b\u0438 \u0432\u044b\u0448\u0435:<\/p>\n<pre><code class=\"haskell\">{- \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0442\u0438\u043f \u0438  \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 - \u043e\u0434\u043d\u043e \u0438\u0437 \u0442\u0435\u0445, \u0447\u0442\u043e \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u043b\u0438 \u0440\u0430\u043d\u0435\u0435 -} data TypedExpr = TypedExpr ExprType Expr<\/code><\/pre>\n<p>\u041d\u043e \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u043e \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e &#8212; &#171;\u0432\u043d\u0443\u0442\u0440\u0438&#187; <code>TypedExpr<\/code> \u0432\u0441\u0435 \u0435\u0449\u0435 \u043b\u0435\u0436\u0438\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 <code>Expr<\/code>. \u0420\u0435\u0448\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b \u044f &#8212; \u043d\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435, \u043d\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0430\u0434\u043e. \u042d\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 &#171;\u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430&#187; <code>TExpr<\/code> \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 <code>TypedExpr<\/code>. \u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 &#8212; <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-03\/app\/Syntax.hs#L54\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>. \u041f\u0440\u0435\u043b\u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 (\u0432 \u0442\u043e\u043c \u0436\u0435 \u043c\u0435\u0441\u0442\u0435 \u0433\u0434\u0435 \u0438 <code>ExprType<\/code>), \u043e\u0434\u043d\u0430\u043a\u043e \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u0435\u043d \u0438 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0438\u0434\u0438\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u043d. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0435\u0433\u043e \u0442\u0435\u0440\u043d\u0438\u0441\u0442\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u043f\u043e\u0434 \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u043e\u043c, \u0430 \u043c\u044b \u0438\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u041c\u043e\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u0441 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0422\u0443\u0442-\u0442\u043e \u0438 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0445 \u0441\u0445\u0435\u043c.<\/p>\n<p>\u041a\u0430\u043a \u044f \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u0443, \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435, \u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 &#8212; \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0438\u0437 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u043f\u0435\u0442-\u043f\u0440\u043e\u0434\u0436\u0435\u043a\u0442\u043e\u0432 \u0441\u0430\u043c\u044b\u0439 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e. \u041a\u043e\u0433\u0434\u0430 \u044f, \u043f\u043e\u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u0441 \u043a\u043e\u0440\u0438\u0444\u0435\u044f\u043c\u0438, \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 \u0434\u0435\u0440\u0435\u0432\u043e \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/blog.sumtypeofway.com\/posts\/introduction-to-recursion-schemes.html\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u0441\u0445\u0435\u043c\u044b<\/a> \u0438\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e <a href=\"http:\/\/comonad.com\/reader\/2009\/incremental-folds\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0430\u043a\u043e\u0435<\/a> (\u0431\u043b\u0438\u0437\u043a\u043e\u0435 \u043f\u043e \u0441\u043c\u044b\u0441\u043b\u0443),  &#8212; \u044f \u0443\u0436\u0435 \u0438\u043c\u0435\u043b \u043f\u0430\u0440\u0441\u0435\u0440 \u0438 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0441 <code>Expr<\/code>.<\/p>\n<p>\u041f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0442\u0438\u043f\u043e:<\/p>\n<pre><code class=\"haskell\">data Expr' e = Int Integer | Call String [e]<\/code><\/pre>\n<p>\u0418 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c:<\/p>\n<ul>\n<li>\n<p><code>type Expr = Expr' Expr<\/code> &#8212; \u0440\u0443\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0446\u0438\u043a\u043b \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438<\/p>\n<\/li>\n<li>\n<p><code>type Expr = Expr' Expr'<\/code> &#8212;  \u0440\u0443\u0433\u0430\u0435\u0442\u0441\u044f, \u0432\u043f\u043e\u043b\u043d\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e <code>Expr'<\/code> \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430<\/p>\n<\/li>\n<li>\n<p><code>newtype Expr = Expr (Expr' Expr)<\/code> &#8212; \u0430 \u044d\u0442\u043e \u0443\u0436\u0435 \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u043c \u0441\u0445\u0435\u043c\u0430\u043c, \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Fix<\/code>, \u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u044f \u0441\u043b\u043e\u043c\u0430\u043b\u0441\u044f<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u043d\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0439\u0442\u0435 \u043c\u043e\u0438\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u0441\u0440\u0430\u0437\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b, <code>Data.Fix<\/code> \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u043f\u0440\u0435\u043b\u0435\u0441\u0442\u0438. \u042f \u0436\u0435 \u0440\u0435\u0448\u0438\u043b &#8212; \u0441\u0434\u0435\u043b\u0430\u0435\u043c <code>TypedExpr<\/code> \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u043c <code>Expr<\/code>, \u043d\u043e \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0449\u0438\u043c\u0438 \u043f\u043e\u043f\u0440\u0430\u0432\u043a\u0430\u043c\u0438. \u0418\u0434\u0435\u044f \u0442\u0430\u043a\u0430\u044f &#8212; \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u0434\u0435\u0440\u0435\u0432\u043e \u0438\u0437 <code>Expr<\/code>, \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0435\u0433\u043e \u0432 \u0434\u0435\u0440\u0435\u0432\u043e \u0442\u0438\u043f\u0430 <code>TypedExpr<\/code> &#8212; \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u0441\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b.<\/p>\n<p>\u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b (\u0441 \u0437\u0430\u043c\u0435\u043d\u043e\u0439 <code>Expr<\/code> \u043d\u0430 <code>TypedExpr<\/code>) \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 <code>TypedExpr<\/code>, \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u043e \u0432\u0441\u0435 \u0442\u0438\u043f\u044b &#8212; <code>data TypedExpr = ... | TBlock ExprType (CodeBlock TypedExpr)<\/code>, \u043d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 &#171;\u0442\u0438\u043f&#187; \u044d\u0442\u043e \u043d\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f, \u0430 &#171;\u0447\u0430\u0441\u0442\u044c&#187; \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 &#8212; \u043c\u043d\u0435 \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0438\u043f \u043d\u0435 \u0432\u043e \u0432\u0441\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b, \u0430 \u0432 \u043e\u0434\u0438\u043d, &#171;\u0433\u043b\u0430\u0432\u043d\u044b\u0439&#187; &#8212; <code>data TypedExpr = ... |  TypedExpr ExprType TypedExpr<\/code> &#8212; \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0435 TypedExpr \u0441\u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a &#171;\u0433\u043b\u0430\u0432\u043d\u043e\u0435&#187; \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u0438 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u044b \u0431\u0435\u0437 \u0442\u0438\u043f\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u0430\u0440\u0438\u0430\u043d\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f<\/strong> &#8212; \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0442\u0438\u043f <code>TExpr<\/code>, \u0441 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c\u0438 <code>Expr<\/code>, \u043d\u043e \u0441\u0441\u044b\u043b\u0430\u044e\u0449\u0438\u043c\u0438\u0441\u044f \u043d\u0430 <code>TypedExpr<\/code> (\u0442.\u0435. \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0434\u0435\u0440\u0435\u0432\u0430, \u0441 &#171;\u0443\u0437\u043b\u0430\u043c\u0438&#187; \u0438\u0437 <code>TypedExpr<\/code>), \u0438 \u0442\u0438\u043f <code>data TypedExpr = TypedExpr ExprType TExpr<\/code>. \u0412\u043c\u0435\u0441\u0442\u0435 \u0441 view-\u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430\u043c\u0438 \u044d\u0442\u043e \u0432 \u043a\u043e\u0434\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u043d\u043e \u0434\u0430\u043b\u0435\u0435.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<h4>\u041c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0438\u043f\u0430\u043c\u0438<\/h4>\n<blockquote>\n<p>\u0420\u0430\u0434\u0438 \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u0441\u0442\u0438, \u0438 \u0447\u0442\u043e\u0431 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0433\u0434\u0435 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c, \u044f \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0432\u0441\u0435 \u0441\u0432\u043e\u0438 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 <code>TODO<\/code>-\u043f\u043e\u043c\u0435\u0442\u043a\u0438 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u0445.<\/p>\n<\/blockquote>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0448\u0430\u0433\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c <code>AST<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430. &#171;\u0412\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0430\u044f&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u044f &#8212; <code>processAST<\/code> &#8212; \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0430 <span>\u0442\u0443\u0442<\/span> \u0438 \u043b\u0438\u0431\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>AST<\/code> \u0432 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (<code>TAST<\/code>), \u043b\u0438\u0431\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0448\u0438\u0431\u043e\u043a. \u0412\u0441\u0435, \u0447\u0442\u043e \u043e\u043d\u0430 \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0430\u043c\u0430 &#8212; \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e <code>AST<\/code> (\u0441\u0435\u0439\u0447\u0430\u0441 \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e <code>desugarFunc<\/code> &#8212; \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0438\u0437 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 &#171;\u0441\u0430\u0445\u0430\u0440\u0430&#187; \u0432 \u0432\u0438\u0434\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u043d\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0438 \u044f\u0432\u043d\u043e\u0433\u043e \u0435\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0446\u0435 \u0442\u0435\u043b\u0430), \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0435\u0435\u0441\u044f \u0432 <code>annotateTypes<\/code> (\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 <code>deduceType<\/code> \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e <code>expr<\/code>), \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 <code>deduceType<\/code> \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f &#8212; \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 <code>expr<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0435\u0441\u043b\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0439\u0434\u0435\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e, &#171;\u0437\u0430\u043c\u0435\u043d\u0438\u0442\u0441\u044f&#187; \u0441\u0432\u043e\u0438\u043c typed-\u0430\u043d\u0430\u043b\u043e\u0433\u043e\u043c, \u0438 &#171;\u043a\u0430\u0440\u0442\u0443 \u0442\u0438\u043f\u043e\u0432&#187; &#8212; \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 &#171;\u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0445 \u0435\u0434\u0438\u043d\u0438\u0446&#187; (\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0444\u0443\u043d\u043a\u0446\u0438\u0439) \u0441 \u0438\u0445 \u0442\u0438\u043f\u0430\u043c\u0438 &#8212; \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u0443\u0441\u0442\u043e\u0439, \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0439\u0441\u044f \u043f\u043e \u043c\u0435\u0440\u0435 \u0443\u0433\u043b\u0443\u0431\u043b\u0435\u043d\u0438\u044f \u0432 \u0434\u0435\u0440\u0435\u0432\u043e. \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0442\u0438\u043f\u043e\u0432 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u0441\u043c\u0430\u0442\u0438\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438, \u043b\u0438\u0431\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0437 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (int + int = int, int \/ int = float \u0438 \u0442.\u0434.). <code>auto<\/code> \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e &#8212; \u0435\u0441\u043b\u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u0441\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0438\u043b\u0438 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438), \u0442\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e\u0442 \u0442\u0438\u043f, \u0438\u043d\u0430\u0447\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 &#8212; <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-03\/app\/AST\/Typing.hs\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>, \u043b\u0438\u0431\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 step-03\/AST\/Typing.hs.<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c <code>processAST<\/code> \u0432 <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-03\/app\/Main.hs#L31\" rel=\"noopener noreferrer nofollow\">main<\/a> \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0442\u043e \u043d\u0430\u043c \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a:<\/p>\n<pre><code class=\"cpp\">int main() = {     int i = 0;     if (i &lt; 1) {         0;     }     else {          1;     }; };<\/code><\/pre>\n<p>\u0422\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"diff\">Function (() -> int) main [] {   BinaryOp i= (Def int \"i\") (int 0)   If int (BinaryOp b&lt; (Var int \"i\") (int 1)) {     int 0   }   else {     int 1   } }<\/code><\/pre>\n<p>\u0422\u0443\u0442 <code>i=<\/code> &#8212; \u0438\u043d\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u0435, \u0430 <code>b&lt;<\/code> &#8212; \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f (\u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e) \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 bool.<\/p>\n<p><a class=\"anchor\" name=\"part-3\" id=\"part-3\"><\/a><\/p>\n<h2>\u041a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0441 LLVM<\/h2>\n<p><code>\u0428\u0410\u0413 4<\/code><\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 LLVM \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0433\u0434\u0430 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 llvm-hs (<a href=\"https:\/\/github.com\/llvm-hs\/llvm-hs\" rel=\"noopener noreferrer nofollow\">github<\/a>, <a href=\"https:\/\/hackage.haskell.org\/package\/llvm-hs\" rel=\"noopener noreferrer nofollow\">hackage<\/a>), \u043a\u043e\u0442\u043e\u0440\u0443\u044e, \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438, \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0412 \u043c\u043e\u0435\u043c stack.yaml \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>extra-deps: - llvm-hs-9.0.1 - llvm-hs-pure-9.0.0 - llvm-hs-pretty-0.9.0.0<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0436\u0435 \u0432\u044b \u0438\u0434\u0435\u0442\u0435 \u043f\u043e \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0443 \u043f\u043e \u0448\u0430\u0433\u0430\u043c \u0438\u0437 <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f<\/a>, \u0442\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u0435 \u0432 <strong>step-04<\/strong>.<\/p>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438 \u0441\u0430\u043c\u0443 LLVM &#8212; \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 llvm-hs. <a href=\"https:\/\/github.com\/llvm-hs\/llvm-hs\/tree\/3d08076125057e64702c5f4f189852ecae326cdd#installing-llvm\" rel=\"noopener noreferrer nofollow\">\u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f<\/a>. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0449\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 &#8212; <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-04\/stack.yaml\" rel=\"noopener noreferrer nofollow\">stack.yaml<\/a> \u0438 <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-04\/habrhs.cabal\" rel=\"noopener noreferrer nofollow\">habrhs.cabal<\/a><\/p>\n<h3>\u0418\u0437 TAST \u0432 IR<\/h3>\n<p>\u042d\u0442\u043e &#8212; \u0444\u0438\u043d\u0438\u0448\u043d\u0430\u044f \u043f\u0440\u044f\u043c\u0430\u044f. \u0422\u0443\u0442 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c <code>Codegen<\/code>, \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0435\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f &#8212; <code>buildIR<\/code>, \u0432\u044b\u0434\u0430\u044e\u0449\u0430\u044f \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 LLVM IR. \u0421\u0440\u0430\u0437\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u043e\u0442 \u044d\u0442\u0430\u043f \u0432 <code>main<\/code> <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-04\/app\/Main.hs#L41\" rel=\"noopener noreferrer nofollow\">\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/a>, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 (\u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 &#8212; \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043c\u043d\u043e\u0433\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432 \u0438 \u0444\u043b\u0430\u0433 &#8212;emit).<\/p>\n<p><code>Codegen<\/code> \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0442\u0440\u0435\u0445 \u0444\u0430\u0439\u043b\u043e\u0432, \u0433\u043b\u0430\u0432\u043d\u044b\u0439 &#8212; <code>Builder.hs<\/code>, \u0433\u0434\u0435 \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f IR, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c (\u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0442\u0443\u0442 \u0432\u0435\u0437\u0434\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043c\u043e\u0434\u0443\u043b\u0438 <code>LLVM.*<\/code>, \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 &#171;\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043d\u044b\u043c\u0438&#187; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u0442\u0438\u043f\u043e allocate \u0438\u043b\u0438 reference &#8212; \u044d\u0442\u043e \u043e\u0442\u0442\u0443\u0434\u0430).<\/p>\n<p><strong>1) <\/strong><a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-04\/app\/Codegen\/ASTBridge.hs\" rel=\"noopener noreferrer nofollow\"><strong>ASTBridge<\/strong><\/a> &#8212; \u0440\u0430\u0437\u043d\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u0442\u0438\u043f\u043e\u0432 \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0433\u043e TAST \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0449\u0438\u0435 \u0434\u043b\u044f LLVM<\/p>\n<ul>\n<li>\n<p><code>typeMap<\/code> &#8212; \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0438\u0437 \u043f\u0430\u0440 &#171;\u043d\u0430\u0448 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0438\u043f\u0430&#187; &#8212; &#171;\u0442\u0438\u043f \u0432 LLVM&#187;<\/p>\n<\/li>\n<li>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0438\u0434\u0430 <code>allocateX<\/code> &#8212; \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0432\u044b\u0437\u043e\u0432\u043e\u0432 LLVM \u0434\u043b\u044f \u0430\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u0438 \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u043e\u0434 \u0441\u0430\u043c \u0442\u0438\u043f \u0438\u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043d\u0435\u0433\u043e.<\/p>\n<\/li>\n<li>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0438\u0434\u0430 <code>referenceX<\/code> &#8212; \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 LLVM-\u043d\u044b\u0445 &#171;\u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439&#187; \u043a \u044f\u0447\u0435\u0439\u043a\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u043e\u0434 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0442\u0438\u043f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u043b\u0438 \u043f\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044e<\/p>\n<\/li>\n<li>\n<p><code>convert<\/code> &#8212; \u043f\u043e \u043d\u0430\u0448\u0438\u043c <code>IntType<\/code> \u0438 <code>FloatType<\/code> \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432 \u0434\u043b\u044f LLVM<\/p>\n<\/li>\n<li>\n<p><code>opTable<\/code> \u0438 <code>findOperation<\/code> &#8212; \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0432 \u043d\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u0421\u043b\u043e\u0432\u0430\u0440\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u043b\u044f <code>IntType<\/code> \u0438 <code>FloatType<\/code> \u0435\u0449\u0435 \u043f\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u043c\u0443 \u0441\u043b\u043e\u0432\u0430\u0440\u044e, \u0441 \u043f\u0430\u0440\u0430\u043c\u0438 &#171;\u0441\u0442\u0440\u043e\u043a\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438&#187; (+, -, &#8230;.) &#8212; &#171;LLVM \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0442\u0438\u043f\u0430&#187; (\u0438\u043d\u0442\u043e\u0432\u043e\u0435 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435, \u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0442.\u0434.)<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u0438\u0437 \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439) \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Operand<\/code> &#8212; \u044d\u0442\u043e LLVM-\u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0438\u0439, \u043a\u0430\u043a \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u043e\u043f\u0435\u0440\u0430\u043d\u0434 &#8212; \u043d\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0430 \u043d\u0435\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0438\u043b\u0438 &#171;\u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e&#187; (store \u0432 llvm), \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u0435 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430. <code>findOperation<\/code> \u0436\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 (\u0430 <code>opTable<\/code> &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442) \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0435 \u0434\u0432\u0430 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0435 \u0442\u0440\u0435\u0442\u0438\u0439 &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0445 <code>reference<\/code> \u0438 <code>allocate<\/code>, \u0442\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u043c\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0438\u0437 LLVM. \u042d\u0442\u043e <code>named<\/code>, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 <code>AST.PointerType<\/code>, \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 LLVM-\u0442\u0438\u043f \u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 qualified \u0438\u043c\u044f \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u0438\u0437 &#171;\u043d\u0430\u0448\u0435\u0433\u043e&#187; AST, \u0430 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <code>LLVM.AST<\/code>.<\/p>\n<p><strong>2) <\/strong><a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-04\/app\/Codegen\/Primitives.hs\" rel=\"noopener noreferrer nofollow\"><strong>Primitives<\/strong><\/a> &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 LLVM. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0431\u044a\u044f\u0432\u043b\u043d\u0438\u0435 <em>\u0442\u0438\u043f\u0430<\/em> \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043d\u0430 int \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438 \u0432\u0438\u0434 \u0438\u043d\u0442\u0430 (i16, i32, i64). \u041c\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e 4, i32 \u0438 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u0435 \u0430\u0434\u0440\u0435\u0441\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e &#8212; \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u0434\u043e\u0431\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u0430\u0440\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u0440\u0430\u0437\u0443. \u0422\u0430\u043a\u0438\u0435 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c.<\/p>\n<p>\u0418, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0442\u043e, \u0440\u0430\u0434\u0438 \u0447\u0435\u0433\u043e \u043c\u044b \u0442\u0443\u0442 \u0441\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c &#8212; <strong>\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f IR \u0438\u0437 AST<\/strong>, \u043c\u043e\u0434\u0443\u043b\u044c <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-04\/app\/Codegen\/Builder.hs\" rel=\"noopener noreferrer nofollow\">Builder<\/a>. <\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u043c\u0443 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430, \u043f\u043e \u0441\u0443\u0442\u0438 \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043b\u0438\u0448\u044c \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f <code>TypedExpr<\/code> \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b (\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f) &#8212; <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-04\/app\/Codegen\/Builder.hs#L28\" rel=\"noopener noreferrer nofollow\"><strong>emit<\/strong><\/a> (\u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 &#8212; \u0435\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434). \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438, \u0447\u0442\u043e \u0432\u0441\u0435 \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f &#8212; \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0438\u0445 \u043e\u0441\u043e\u0431\u044b\u043c \u043a\u0435\u0439\u0441\u043e\u043c, \u0438 \u0442\u043e\u0433\u0434\u0430 \u0432\u0441\u044f \u0441\u0445\u0435\u043c\u0430 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>TAST (\u0442\u043e \u0435\u0441\u0442\u044c [TypedExpr]) -> buildIR -> LLVM Module, \u0433\u0434\u0435  1) buildIR: \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 TypedExpr (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f) buildFunction  2) buildFunction: \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 IR \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0435\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435, \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u0443\u0435\u0442 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b,    \u0438 \u0437\u0430\u0442\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043b\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e funcBodyBuilder -> buildCodeBlock 3) buildCodeBlock: \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 emit \u043a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0438 \u0435\u0433\u043e \u0447\u0430\u0441\u0442\u044f\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e, \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435    (\u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \"\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c\" \u0432 \u0431\u043b\u043e\u043a\u0435 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 AST, \u043f\u043e\u043c\u043d\u0438\u0442\u0435?)<\/code><\/pre>\n<p>\u0422\u0438\u043f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>emit<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 &#8212; <code>emit :: (MonadFix m, MonadIRBuilder m) => TypedExpr -> m Operand<\/code>. \u0422\u043e \u0435\u0441\u0442\u044c \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043c\u043e\u043d\u0430\u0434\u043e\u0439 <code>IRBuilder<\/code> \u0438\u0437 LLVM &#8212; \u044d\u0442\u043e \u043a\u0440\u0430\u0439\u043d\u0435 \u0443\u0434\u043e\u0431\u043d\u043e, \u0442.\u043a. \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e do-\u0431\u043b\u043e\u043a\u0430 \u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u0446\u0438\u0439 LLVM \u043c\u044b, \u043f\u043e \u0441\u0443\u0442\u0438, \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c (\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0430\u0442\u0442\u0435\u0440\u043d-\u043c\u0430\u0442\u0447\u0438\u043d\u0433\u0430) \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043a\u043e\u0439 \u0435\u043c\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 IR-\u043a\u043e\u0434 \u043f\u043e\u0447\u0442\u0438 \u043e\u0434\u0438\u043d-\u0432-\u043e\u0434\u0438\u043d \u0434\u043b\u044f \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0433\u043b\u0430\u0437\u0430. \u0422.\u043a. \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u0437 \u0442\u043e\u0433\u043e \u0447\u0442\u043e &#171;\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u0438 LLVM \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0434\u0430\u043b\u0435\u0435 \u043f\u043e \u043c\u043e\u043d\u0430\u0434\u0435, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 <code>emit<\/code> &#8212; \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e.<\/p>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440 (\u0442\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>view<\/code> \u0432 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0435 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 &#8212; \u043e\u043d\u0430 \u0441\u0440\u0430\u0437\u0443 \u0434\u043e\u0441\u0442\u0430\u0435\u0442 \u0442\u0438\u043f \u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f) &#8212; \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f <code>If<\/code>:<\/p>\n<pre><code class=\"haskell\">-- type_ - \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0431\u043b\u043e\u043a\u0430 emit (view -> (type_, TIf cond blockTrue blockFalse)) = mdo   -- \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c IR \u0434\u043b\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u044f If (\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c emit), \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0430 \"x &lt; y\"   condition &lt;- emit cond   -- \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0431\u0443\u0434\u0443\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0431\u043b\u043e\u043a\u0430   -- \u0438 \u0432 \u043d\u0435\u0433\u043e \u0437\u0430\u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u043e\u0439 \u0432\u0435\u0442\u043a\u0438   resultPointer &lt;- allocateT type_   -- \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0438 \u0432\u044b\u0431\u043e\u0440 \u0432\u0435\u0442\u043a\u0438   condBr condition trueBranch falseBranch   -- \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f IR \u0434\u043b\u044f \u0432\u0435\u0442\u043a\u0438 if (...) { }   trueBranch &lt;- buildBranch \"true\" blockTrue resultPointer $ Just mainBr   -- \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f IR \u0434\u043b\u044f \u0432\u0435\u0442\u043a\u0438 else { }   falseBranch &lt;- buildBranch \"false\" blockFalse resultPointer $ Just mainBr   -- \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 \"\u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0432\u0435\u0442\u043a\u0443\" \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442   (mainBr, result) &lt;- emitExit resultPointer   return result<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0442\u0438\u043b\u0438\u0442\u0430\u0440\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u0421\u0430\u043c\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f &#8212; <code>emitExit<\/code>, \u043e\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u0434 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0431\u043b\u043e\u043a\u0430 \u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430:<\/p>\n<pre><code class=\"haskell\">emitExit resultPointer = do   mainBr &lt;- block `named` bodyLabel   result &lt;- load resultPointer   return (mainBr, result)<\/code><\/pre>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f &#8212; <code>buildBranch<\/code>. \u0410\u043d\u0430\u043b\u043e\u0433\u0438 \u0432\u0435\u0442\u043e\u043a \u0435\u0441\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0443 <code>If<\/code>, \u043d\u043e \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435 \u0438 \u0443 \u0446\u0438\u043a\u043b\u043e\u0432, \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043c \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u044b\u0436\u043e\u043a \u0432 \u043d\u0430\u0447\u0430\u043b\u043e.<\/p>\n<pre><code class=\"haskell\">-- \u0442\u0443\u0442 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u043c\u044f, \u0441\u043f\u0438\u0441\u043e\u043a expr \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 (codeBlock), \u0438 \u0443\u0436\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 resultPointer - \u043a\u0443\u0434\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 buildBranch name codeBlock resultPointer mNext =   do     -- \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 - \u043c\u0435\u0442\u043a\u0430 \u0434\u043b\u044f LLVM     branch &lt;- block `named` name     -- \u043e\u043f\u044f\u0442\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c emit, \u0441\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043f\u043e\u0434 buildCodeBlock     blockR &lt;- buildCodeBlock codeBlock     -- \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044e     store resultPointer blockR     -- \u0435\u0441\u043b\u0438 \u043d\u0430\u0434\u043e \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u0432\u0435\u0442\u043a\u0438 - \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u044b\u0436\u043e\u043a, \u0438\u043d\u0430\u0447\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c     case mNext of       Nothing -> pure ()       Just label -> br label     -- \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u0431\u043b\u043e\u043a     return branch<\/code><\/pre>\n<p>\u0420\u0430\u0441\u043f\u0438\u0441\u0430\u0432 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c <code>emit<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u0438\u0434\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 (\u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-04\/app\/Codegen\/Builder.hs#L34\" rel=\"noopener noreferrer nofollow\">\u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443<\/a>), \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 IR \u043a\u043e\u0434\u0430. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0432 \u0438\u0442\u043e\u0433\u0435 \u0434\u043b\u044f <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-04\/main.grt\" rel=\"noopener noreferrer nofollow\">\u0432\u0441\u0435 \u0442\u043e\u0439 \u0436\u0435<\/a> \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0442\u0435 \u043a\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0442 \u043f\u043e \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0443 &#8212; \u044d\u0442\u043e <code>main.grt<\/code>).  \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c <code>stack run -- -e main.grt<\/code> \u0435\u0449\u0435 \u0440\u0430\u0437 \u0438 \u043f\u043e\u043b\u044e\u0431\u0443\u0435\u043c\u0441\u044f \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 (\u0444\u043b\u0430\u0433 -e \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043f\u0435\u0447\u0430\u0442\u0438 IR &#8212; \u0432\u0435\u0434\u044c \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u044b \u0443\u0436\u0435 \u0440\u0430\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u043a\u043e\u0440\u043e \u0438\u043c\u0435\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u0430 \u043e\u043d\u0438 \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0432\u044b\u0432\u043e\u0434\u044f\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d IR):<\/p>\n<pre><code>; ModuleID = 'program'  define external ccc  i32 @main()    { Body_0:   %i_0 = alloca i32, align 4    store  i32 0, i32* %i_0, align 4    %0 = load  i32, i32* %i_0, align 4    %1 = icmp slt i32 %0, 1    %2 = alloca i32, align 4    br i1 %1, label %true_0, label %false_0  true_0:   store  i32 0, i32* %2, align 4    br label %Body_1  false_0:   store  i32 1, i32* %2, align 4    br label %Body_1  Body_1:   %3 = load  i32, i32* %2, align 4    ret i32 %3  }<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0431\u0435\u0437 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u0435\u0435 \u0447\u0435\u043c &#171;\u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c&#187;, \u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0441 \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u0443\u0447\u0448\u0435 &#8212; \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u0435\u0435. \u0423\u0440\u0430, \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0438\u043c\u0435\u0435\u043c LLVM IR \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u0438\u0432 \u0432\u044b\u0432\u043e\u0434 \u0432 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0434\u0430\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 <code>lli<\/code> &#8212; \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0443 IR.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b, \u0442\u043e \u0434\u0435\u043b\u043e \u0437\u0430 \u043c\u0430\u043b\u044b\u043c &#8212; \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c\u0443 \u0432 LLVM \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u0435\u0439.<\/p>\n<details class=\"spoiler\">\n<summary>\u0411\u043e\u043d\u0443\u0441: \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a<\/summary>\n<div class=\"spoiler__content\">\n<p>\u042d\u0442\u043e \u0443\u0436\u0435 <code>\u0428\u0410\u0413 5<\/code>, \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f <code>step-05<\/code>.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e &#8212; \u0431\u043b\u0430\u0433\u043e, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 llvm-hs \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u043e\u0431\u0435\u0440\u0442\u043a\u0438. \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443, \u0432\u0441\u0435 \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c &#8212; \u044d\u0442\u043e \u0441\u043a\u043b\u0435\u0438\u0442\u044c <a href=\"https:\/\/hackage.haskell.org\/package\/llvm-hs-9.0.1\/docs\/LLVM-Internal-Context.html#v:withContext\" rel=\"noopener noreferrer nofollow\">\u043f\u0443\u0441\u0442\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442<\/a>, <a href=\"https:\/\/hackage.haskell.org\/package\/llvm-hs-9.0.1\/docs\/LLVM-Internal-Target.html#v:withHostTargetMachineDefault\" rel=\"noopener noreferrer nofollow\">\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0445\u043e\u0441\u0442\u043e\u0432\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/a>, \u0441\u043e\u0437\u0434\u0430\u0442\u044c llvm-\u043c\u043e\u0434\u0443\u043b\u044c \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e <code>LLVM.AST.Module<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/hackage.haskell.org\/package\/llvm-hs-9.0.1\/docs\/LLVM-Module.html#v:withModuleFromAST\" rel=\"noopener noreferrer nofollow\">\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/a>, \u0438 \u0441\u043a\u043e\u0440\u043c\u0438\u0442\u044c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <a href=\"https:\/\/hackage.haskell.org\/package\/llvm-hs-9.0.1\/docs\/LLVM-Module.html#v:writeObjectToFile\" rel=\"noopener noreferrer nofollow\">\u0431\u0438\u043b\u0434\u0435\u0440\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u0438\u043a\u043e\u0432<\/a>, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0441\u043b\u0438\u043d\u043a\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041a\u043e\u0434 \u0434\u043b\u044f \u0434\u0435\u0448\u0451\u0432\u043e\u0433\u043e \u0438 \u0441\u0435\u0440\u0434\u0438\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a (<a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-05\/app\/Compiler.hs\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u043b\u043d\u044b\u0439 \u0444\u0430\u0439\u043b<\/a>):<\/p>\n<pre><code class=\"haskell\">writeWithDefaultTarget :: File -> Module -> IO () writeWithDefaultTarget file mod = withHostTargetMachineDefault (\\t -> writeObjectToFile t file mod)  writeWithModuleFromAST :: File -> Context -> LLVM.AST.Module -> IO () writeWithModuleFromAST f c m = withModuleFromAST c m (writeWithDefaultTarget f)  writeObject :: File -> LLVM.AST.Module -> IO () writeObject file mod = withContext (\\c -> writeWithModuleFromAST file c mod)<\/code><\/pre>\n<p>\u0418 \u0442\u0430\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 main (<a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-05\/app\/Main.hs\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u043b\u043d\u044b\u0439 \u0444\u0430\u0439\u043b<\/a>):<\/p>\n<pre><code class=\"haskell\">writeObject (File (\"output.o\" :: FilePath)) ir<\/code><\/pre>\n<p>\u0421 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u044d\u0442\u043e\u0433\u043e, \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u0439\u043b <code>output.o<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0441\u043b\u0438\u043d\u043a\u043e\u0432\u0430\u0442\u044c \u0432\u0430\u0448\u0438\u043c \u043b\u044e\u0431\u0438\u043c\u044b\u043c \u043b\u0438\u043d\u043a\u0435\u0440\u043e\u043c &#8212; \u0443 \u043c\u0435\u043d\u044f \u043d\u0430 \u043c\u0430\u043a\u0435 \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a <code>ld -lSystem output.o -o output<\/code>.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432\u0432\u043e\u0434\/\u0432\u044b\u0432\u043e\u0434 \u043c\u044b \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438, \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043a\u043e\u0434\u0430\u043c\u0438. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043e, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u0430\u0432 exit code \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b. \u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0443\u0442\u0438\u043b\u0438\u0442\u0430\u0440\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 (\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 macOS) \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043d\u0430\u0448 \u043a\u043e\u043c\u043f\u043b\u0438\u044f\u0442\u043e\u0440, \u043b\u0438\u043d\u043a\u0443\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0443\u044e\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0438 \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"bash\">#!\/usr\/bin\/env bash stack run -- main.grt  ld -lSystem output.o -o output chmod +x output .\/output  echo $?<\/code><\/pre>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"part-4\" id=\"part-4\"><\/a><\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u043f\u0440\u043e\u0448\u043b\u0438 \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u044d\u0442\u0430\u043f\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 &#8212; \u043f\u0430\u0440\u0441\u0435\u0440, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 AST, \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f IR, \u0434\u0430\u0436\u0435 \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u043b\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u0418\u043d\u0430\u0447\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, \u043c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0438 \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0431\u044d\u043a\u0435\u043d\u0434\u043e\u043c (LLVM). \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043a\u0430\u043a \u044f \u0443\u0436\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b, \u043c\u043d\u043e\u0433\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435 &#8212; \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u044f \u0434\u0430\u043b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b, \u0447\u0442\u043e\u0431\u044b \u0432\u044b \u0441\u043c\u043e\u0433\u043b\u0438 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043c\u043e\u0438\u0445 \u043e\u0448\u0438\u0431\u043e\u043a, \u0430 \u043c\u043e\u0439 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u0441\u0442\u0430\u043b \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439.<\/p>\n<p>\u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u043c (\u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u043d\u0438\u0445), \u0430 \u0442\u0430\u043a\u0436\u0435 PR-\u0430\u043c \u0432 <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a> \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430 &#8212; \u0432\u0435\u0440\u0441\u0438\u044f \u043a\u043e\u0434\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u0435, \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0432 README \u0438 \u0441\u0430\u043c\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0439\u0442\u0438 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u043c\u043e\u0436\u043d\u043e \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442.<\/p>\n<p>\u041b\u044e\u0431\u0438\u0442\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u044f\u0437\u044b\u043a\u0438, \u0438 \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/581234\/\"> https:\/\/habr.com\/ru\/articles\/581234\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041d\u0430 \u0440\u0430\u0431\u043e\u0442\u0435 \u044f \u043f\u0438\u0448\u0443 \u043f\u043e\u0447\u0442\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430 Python, \u0441 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0441\u043a\u043e\u0439 \u0441\u043a\u0430\u043c\u044c\u0438 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f C\/C++, \u0432 \u043e\u0434\u043d\u043e\u043c pet-project \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b Haskell. \u0421 \u0442\u0430\u043a\u0438\u043c \u0431\u0430\u0433\u0430\u0436\u043e\u043c \u0437\u043d\u0430\u043d\u0438\u0439 \u044f \u0432\u0437\u044f\u043b\u0441\u044f \u0437\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 <strong>\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 LLVM<\/strong> &#8212; \u0437\u0430\u0447\u0435\u043c \u0438 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u044f \u0443\u0436\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0432 <a href=\"https:\/\/habr.com\/ru\/post\/508828\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>.<\/p>\n<p>\u042d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u044f \u043f\u0438\u0448\u0443 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u044f, \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d \u0432 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0438 Haskell, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438\u043b\u0438 \u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c\u0441\u044f \u0441 LLVM, \u043d\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u0441 \u043a\u0430\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u0446\u0430 \u043f\u043e\u0434\u043e\u0439\u0442\u0438 \u043a \u0437\u0430\u0434\u0430\u0447\u0435.<\/p>\n<p>\u042f \u043a\u0440\u0430\u0442\u043a\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 <strong>\u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0437\u043d\u0430\u043d\u0438\u0439 Haskell<\/strong>, \u043f\u0440\u043e \u0441\u0432\u043e\u0438 <strong>\u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u043a \u043a\u0430\u043a\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c \u044f \u043f\u0440\u0438\u0448\u0435\u043b<\/strong> &#8212; \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f \u0443\u0437\u043d\u0430\u043b \u043f\u043e\u0437\u0436\u0435 &#8212; \u0438 \u043a\u0430\u043a \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0432\u0430\u0448 pet-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440. \u041d\u0430 \u0432\u0441\u0451 \u044d\u0442\u043e \u044f \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u043c <strong>\u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435<\/strong>.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<hr\/>\n<h3>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/h3>\n<ol>\n<li>\n<p><a href=\"#part-1\" rel=\"noopener noreferrer nofollow\">Haskell &#8212; \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#part-2\" rel=\"noopener noreferrer nofollow\">\u041e\u0441\u043d\u043e\u0432\u044b \u044f\u0437\u044b\u043a\u0430 &#8212; \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u043f\u0430\u0440\u0441\u0435\u0440, AST<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#part-3\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0441 LLVM<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#part-4\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/a><\/p>\n<\/li>\n<\/ol>\n<blockquote>\n<p>\u041a\u043e\u0434 \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0440\u0430\u0437\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u043f\u043e \u0448\u0430\u0433\u0430\u043c: <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/VoidDruid\/habr-hs-llvm<\/a><\/p>\n<\/blockquote>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a &#171;\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0443\u0447\u0435\u0431\u043d\u0438\u043a&#187; \u0432 \u043f\u0430\u0440\u0435 \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u0435\u0439.<\/p>\n<p><a class=\"anchor\" name=\"part-1\" id=\"part-1\"><\/a><\/p>\n<h2>Haskell &#8212;  \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u0430 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h2>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0438\u0437 \u0432\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043a \u0441\u0442\u0430\u0442\u044c\u0435 &#8212; \u044f \u0432 haskell \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f &#8212; \u043d\u0435 \u043c\u0430\u0441\u0442\u0435\u0440-\u043a\u043b\u0430\u0441\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u0438 \u043d\u0435 \u0443\u0447\u0435\u0431\u043d\u0438\u043a \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u044f\u0437\u044b\u043a\u0443, \u0430 \u0441\u043a\u043e\u0440\u0435\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u043e\u0441\u043e\u0431\u0438\u0435 \u043d\u0430 \u0442\u0435\u043c\u0443 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u043e\u0434\u043e\u0439\u0442\u0438 \u043a \u0436\u0443\u0442\u043a\u043e \u0437\u0432\u0443\u0447\u0430\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 &#8212; \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435, \u0438 \u043d\u0435 \u043f\u043e\u0439\u0442\u0438 \u043d\u0430 \u0434\u043d\u043e \u0438\u0437-\u0437\u0430 &#171;\u043d\u0430\u0441\u043b\u043e\u0435\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438&#187;. \u0414\u0430\u043b\u0435\u0435 \u044f \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 <a href=\"https:\/\/github.com\/VoidDruid\/grit\" rel=\"noopener noreferrer nofollow\">\u0441\u0432\u043e\u0435\u0439 \u0434\u0438\u043f\u043b\u043e\u043c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b<\/a>, \u0432\u044b\u043a\u0438\u043d\u0443\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0438\u0447\u0438, \u043d\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 (\u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440).<\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0433\u043e \u044f \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u043b\u0441\u044f \u0432 haskell, \u043d\u043e \u043a \u043d\u0430\u0447\u0430\u043b\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c \u044f \u0443\u0441\u043f\u0435\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u044d\u0442\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0442\u043e\u043b\u044c\u043a\u043e <a href=\"https:\/\/github.com\/VoidDruid\/telemonitor\" rel=\"noopener noreferrer nofollow\">telegram-\u0431\u043e\u0442\u0430<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043c\u043d\u0435 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0442\u044c \u043b\u0438\u0447\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440. \u0414\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u043e\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0436\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u043c\u0438 \u043f\u043e\u0437\u043d\u0430\u043d\u0438\u044f\u043c\u0438 \u0432 \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e, \u0447\u0442\u043e \u0432\u044b \u0437\u043d\u0430\u0435\u0442\u0435 (\u0445\u043e\u0442\u044f \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0438 \u043f\u043e \u0445\u043e\u0434\u0443):<\/p>\n<ul>\n<li>\n<p>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u044f\u0437\u044b\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0434\u0443\u043b\u0438 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u043a <em>\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c<\/em> \u0441 \u043c\u043e\u043d\u0430\u0434\u0430\u043c\u0438 (\u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043c\u0435\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0438), \u0445\u043e\u0442\u044f \u0431\u044b \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e<\/p>\n<\/li>\n<li>\n<p>do-\u043d\u043e\u0442\u0430\u0446\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>IO \u043c\u043e\u043d\u0430\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u043a\u0443\u0440\u0441\u0438\u044f, \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><em>\u0416\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e<\/em>: typeclasses, \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445, records<\/p>\n<\/li>\n<\/ul>\n<p>\u042f \u043f\u043e\u043f\u044b\u0442\u0430\u044e\u0441\u044c \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u0437\u0430\u0447\u0435\u043c \u0438 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u0430\u044f \u0444\u0438\u0447\u0430 \u044f\u0437\u044b\u043a\u0430, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0430\u044f \u0432 \u043f\u0443\u043d\u043a\u0442\u0435 &#171;<em>\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e<\/em>&#171;, \u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0449\u0435, \u0435\u0441\u043b\u0438 \u0432\u044b \u0441 \u043d\u0438\u043c\u0438 \u0437\u043d\u0430\u043a\u043e\u043c\u044b.<\/p>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e stack &#8212; \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e (<a href=\"https:\/\/docs.haskellstack.org\/en\/stable\/README\/#how-to-install\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f<\/a>), \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u0436\u0435. \u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u043d\u0443\u043b\u044f \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f &#8212; \u043c\u043e\u0436\u043d\u043e \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/VoidDruid\/habr-hs-llvm\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0442 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a>, \u0438 \u0438\u0434\u0442\u0438 \u0432 \u043d\u0435\u043c \u043f\u043e \u0448\u0430\u0433\u0430\u043c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u0435\u0439 (readme \u0435\u0441\u0442\u044c \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u043f\u043b\u044e\u0441 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 &#8212; \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u044c\u0442\u0435\u0441\u044c \u0441 \u043d\u0438\u043c\u0438, \u0447\u0442\u043e\u0431 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u0434\u0430). \u0418\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u0441\u0435 \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0432 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 &#8212; \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0430\u043c\u043e\u0433\u043e stack (<a href=\"https:\/\/docs.haskellstack.org\/en\/stable\/README\/#start-your-new-project\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f<\/a>) \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044d\u0442\u043e\u0442 <a href=\"https:\/\/github.com\/ProjectTemplates\/haskell-simple\" rel=\"noopener noreferrer nofollow\">\u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f cookiecutter<\/a>.<\/p>\n<blockquote>\n<p><a href=\"https:\/\/eax.me\/haskell-stack\/\" rel=\"noopener noreferrer nofollow\">\u041d\u0435\u043f\u043b\u043e\u0445\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f<\/a> \u0434\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445 \u043f\u0440\u043e stack \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c<\/p>\n<p>\u041a\u043d\u0438\u0433\u0430 \u043f\u0440\u043e haskell \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a <a href=\"http:\/\/learnyouahaskell.com\/chapters\" rel=\"noopener noreferrer nofollow\">\u043e\u043d\u043b\u0430\u0439\u043d-\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a<\/a>  <\/p>\n<\/blockquote>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 \u043a\u043e\u0434\u043e\u043c \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0441 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u043c \u0440\u0430\u0437\u0431\u043e\u0440\u043e\u043c, \u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u0439\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435, \u0437\u0430\u0439\u0434\u0438\u0442\u0435 \u0432 \u043f\u0430\u043f\u043a\u0443 <code>step-00<\/code>, \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 <code>stack run<\/code>. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441 \u0432\u0430\u043c\u0438 \u043f\u043e\u0437\u0434\u043e\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c, \u0442\u043e \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u0438\u0434\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>step-00<\/code>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 <code>\u0428\u0410\u0413 0<\/code>. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0448\u0430\u0433\u0443 (\u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043a \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0441 \u043a\u043e\u0434\u043e\u043c) \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a &#8212; <code>\u0428\u0410\u0413 \u0425<\/code>.<\/p>\n<p><a class=\"anchor\" name=\"part-2\" id=\"part-2\"><\/a><\/p>\n<h2>\u041e\u0441\u043d\u043e\u0432\u044b \u044f\u0437\u044b\u043a\u0430 &#8212; \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u043f\u0430\u0440\u0441\u0435\u0440, AST<\/h2>\n<h3>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0430\u0440\u0441\u0438\u043d\u0433<\/h3>\n<p><code>\u0428\u0410\u0413 1<\/code><\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c &#8212; \u044d\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0430\u0440\u0441\u0435\u0440. \u0412 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0445\u0430\u0441\u043a\u0435\u043b\u044f \u0435\u0441\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c <em>Parsec<\/em> (Parser Combinators &#8212; <a href=\"https:\/\/hackage.haskell.org\/package\/parsec\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/a>; <a href=\"https:\/\/www.stephendiehl.com\/llvm\/#chapter-2-parser-and-ast\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0443\u0447\u0438\u043b\u0441\u044f \u044f<\/a>), \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0432 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440\u044b. \u0414\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 <code>.cabal<\/code> \u0444\u0430\u0439\u043b \u0432 \u0441\u0435\u043a\u0446\u0438\u044e <code>build-depends<\/code>.<\/p>\n<blockquote>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/50337\/\" rel=\"noopener noreferrer nofollow\">\u0422\u0443\u0442\u043e\u0440\u0438\u0430\u043b<\/a> \u043f\u043e Parsec \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c<\/p>\n<\/blockquote>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435, \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0432\u0441\u0435 \u0435\u0449\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 <code>Main<\/code>. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432:<\/p>\n<pre><code class=\"haskell\">import Text.Parsec (parse) import Text.Parsec.String (Parser) import Text.Parsec.Language (emptyDef) import qualified Text.Parsec.Token as Tok<\/code><\/pre>\n<p>\u0427\u0442\u043e \u043c\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438:<\/p>\n<ul>\n<li>\n<p><code>parse<\/code> &#8212; \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u044e\u0449\u0430\u044f \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0430 \u0432\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p><code>Parser<\/code> &#8212; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u0433\u043e \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438<\/p>\n<\/li>\n<li>\n<p><code>emptyDef<\/code> &#8212; &#171;\u043f\u0443\u0441\u0442\u043e\u0435&#187; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u044f\u0437\u044b\u043a\u0430, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0432\u043e\u0435<\/p>\n<\/li>\n<li>\n<p><code>Text.Parsec.Token<\/code> &#8212; \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438-\u043f\u0430\u0440\u0441\u0435\u0440\u0430\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043b\u0435\u043a\u0441\u0435\u0440\u0430, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>makeTokenParser<\/code>, \u043f\u0435\u0440\u0435\u0434\u0430\u0432 \u0435\u0439 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0430:<\/p>\n<pre><code class=\"haskell\">lexer :: Tok.TokenParser () lexer = Tok.makeTokenParser style   where   ops = [ \"+\", \"*\", \"-\", \"\/\"]   names = [\"if\", \"else\"]   style = emptyDef {   Tok.commentLine = \"\/\/\"   , Tok.commentStart = \"\/*\"   , Tok.commentEnd = \"*\/\"   , Tok.caseSensitive = True   , Tok.reservedOpNames = ops   , Tok.reservedNames = names   }<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 <code>record<\/code> \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>style<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u043d\u0430\u0448\u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043a\u0440\u0430\u0439\u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e &#8212; \u0441\u0438-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438, \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 (<code>+<\/code>, <code>-<\/code>, <code>*<\/code>, <code>\/<\/code>) \u0438 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 <code>if<\/code> \u0438 <code>else<\/code>. \u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u043b\u0435\u043a\u0441\u0435\u0440 \u043c\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c <a href=\"https:\/\/hackage.haskell.org\/package\/parsec-3.1.14.0\/docs\/Text-Parsec-Token.html#t:GenTokenParser\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432<\/a> \u0438\u0437 <code>Tok<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0430:<\/p>\n<pre><code class=\"haskell\">integer    = Tok.integer lexer float      = Tok.float lexer -- \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 - https:\/\/github.com\/VoidDruid\/habr-hs-llvm\/blob\/master\/step-01\/app\/Main.hs<\/code><\/pre>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0446\u0435\u043b\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043c\u043e\u043d\u0430\u0434\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b, \u0438 \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430, \u0442\u043e \u0432\u0438\u0434\u043d\u043e \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438 \u043c\u043e\u043d\u0430\u0434\u0430\u043c\u0438, state-\u0430\u043c\u0438 \u0438 \u0442.\u0434. \u041a\u043e\u0433\u0434\u0430 \u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 Parsec, \u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u043b, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b do-\u043d\u043e\u0442\u0430\u0446\u0438\u044e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0430\u043a \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430\u0445. \u0412\u044b\u0448\u0435 \u044f \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e, \u0442\u0430\u043c \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0447\u0442\u043e <code>ParserT<\/code> \u044d\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u043e\u043d\u0430\u0434\u043d\u044b\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u043a\u0443\u0447\u0430 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 \u043c\u043e\u043d\u0430\u0434\u043d\u044b\u0445 \u0442\u0430\u0439\u043f \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e. \u0414\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0446\u0435\u043b\u0435\u0439 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u0430\u043c\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0430 \u043f\u0430\u0440\u0441\u0435\u0440-\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u043e\u0434\u043d\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u043d\u043e\u0432\u044b\u0435.<\/p>\n<p>\u0417\u043d\u0430\u044f \u044d\u0442\u043e, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u0438\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"haskell\">sumParse :: Parser Integer sumParse = do   first &lt;- integer   reservedOp \"+\"   second &lt;- integer   return (first + second)  runSumParse = parse sumParse \"&lt;stdin>\"<\/code><\/pre>\n<p>\u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u0437 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e-\u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443 \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e, \u0442\u0438\u043f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 <code>Parser \u0427\u0442\u043e\u0423\u0433\u043e\u0434\u043d\u043e<\/code>. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>sumParse<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443, \u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 \u0435\u0435 \u043a\u0430\u043a \u0431\u044b \u043f\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0449\u0435\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 do-\u0431\u043b\u043e\u043a\u0435:<\/p>\n<ul>\n<li>\n<p>\u0411\u0435\u0440\u0435\u0442 \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e <code>first &lt;- integer<\/code><\/p>\n<\/li>\n<li>\n<p>\u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 &#171;+&#187;<\/p>\n<\/li>\n<li>\n<p>\u0411\u0435\u0440\u0435\u0442 \u0432\u0442\u043e\u0440\u043e\u0435 \u0447\u0438\u0441\u043b\u043e <code>second &lt;- integer<\/code><\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f <code>return (first + second)<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u0423 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>runSumParse<\/code> \u043e\u0434\u0438\u043d \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 &#8212; \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043d\u0430 \u0440\u0430\u0437\u0431\u043e\u0440 <code>sumParse<\/code>. <code>\"&lt;stdin>\"<\/code> &#8212;  \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u043d\u0430 &#171;\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a&#187; \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043e\u0439\u0442\u0438 \u0432 ghci (\u043a\u043e\u043c\u0430\u043d\u0434\u0430 <code>stack ghci<\/code>), \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c <code>runSumParse \"1 + 2\"<\/code> &#8212;  \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f <code>Right 3<\/code>. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0447\u0442\u043e \u043d\u0430\u0448 \u043f\u0430\u0440\u0441\u0435\u0440 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a, \u0438 \u0432\u0435\u0440\u043d\u0443\u043b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <code>3<\/code> &#8212; \u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>parse<\/code> \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>Either ParseError a<\/code> &#8212; \u0433\u0434\u0435 <code>a<\/code> &#8212; \u0442\u0438\u043f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 <code>sumParse<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c <code>Integer<\/code>.<\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0434\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0442\u044b \u043f\u043e\u0434 \u044d\u0442\u0438\u043c \u044d\u0442\u0430\u043f\u043e\u043c, \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main<\/code> \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0447\u0438\u0442\u0430\u043b\u0430 \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u0438, \u043f\u0430\u0440\u0441\u0438\u043b\u0430 \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u043b\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<pre><code class=\"haskell\">main = do   line &lt;- getLine   case runSumParse line of   Right result -> putStrLn (\"Result: \" ++ show result)   Left error -> print error<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0423\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u0435 &#8212; \u043f\u0430\u0440\u0441\u0435\u0440 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430 &#8216;1++&#8217;. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0434 \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u043e\u043c<\/summary>\n<div class=\"spoiler__content\">\n<p> \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e &#171;++&#187; \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439: <code>ops = [ \"++\", \"+\", \"*\", \"-\", \"\/\"]<\/code>. \u0417\u0430\u0442\u0435\u043c \u043f\u0438\u0448\u0435\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440:<\/p>\n<pre><code class=\"haskell\">incrParse = do first &lt;- integer   reservedOp \"++\"   return (first + 1)<\/code><\/pre>\n<\/div>\n<\/details>\n<h3>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 AST<\/h3>\n<p><code>\u0428\u0410\u0413 2<\/code><\/p>\n<p>\u041e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u044d\u0442\u0430\u043f\u043e\u0432 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u044f\u0437\u044b\u043a\u0430, \u043f\u043e-\u043c\u043e\u0435\u043c\u0443 \u043e\u043f\u044b\u0442\u0443 &#8212; \u044d\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D0%BE%D0%B5_%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE\" rel=\"noopener noreferrer nofollow\">\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430<\/a>. \u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0443\u0442 \u0437\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0445\u0430\u0441\u043a\u0435\u043b\u0435\u043c, \u043e\u043f\u0438\u0441\u0430\u0442\u044c &#171;\u043e\u0431\u044b\u0447\u043d\u043e\u0435&#187; \u0434\u0435\u0440\u0435\u0432\u043e \u043b\u0435\u0433\u043a\u043e &#8212; \u044d\u0442\u043e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<pre><code class=\"haskell\">data Tree a = Leaf  -- \u0442\u0443\u043f\u0438\u043a | Node a (Tree a) (Tree a)  -- \u0443\u0437\u0435\u043b \u0434\u0435\u0440\u0435\u0432\u0430 - \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0434\u0432\u0435 \"\u044f\u0447\u0435\u0439\u043a\u0438\" \u043f\u043e\u0434 \u0432\u0435\u0442\u043a\u0438 deriving Show<\/code><\/pre>\n<p>\u0422\u0443\u0442 <code>Leaf<\/code> \u0438 <code>Node<\/code> &#8212; \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u0430 <code>Tree a<\/code>, \u0433\u0434\u0435 <code>a<\/code> &#8212; \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0443\u0437\u043b\u044b \u0434\u0435\u0440\u0435\u0432\u0430. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0448\u0435\u043c \u044f\u0437\u044b\u043a\u0435 (\u0435\u0449\u0435 \u0440\u0430\u0437 \u043d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u0445\u043e\u0442\u044c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0438 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0421\u0438, \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u043d\u0435 \u0441\u0438\u0448\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e &#171;\u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e&#187; \u0441\u0438-\u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430):<\/p>\n<pre><code class=\"haskell\">data Expr   = Int Integer  -- \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 Integer   | Var Name  -- \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439   | Def ExprType Name  -- \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439   | Block (CodeBlock Expr)  -- \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430   | Call String [Expr]  -- \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438   | Function ExprType Name [Expr] (Maybe Name) (CodeBlock Expr)  -- \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0434\u0430\u043b\u0435\u0435)   | BinaryOp String Expr Expr  -- \u0431\u0438\u043d\u0430\u0440\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0430\u0434 \u0434\u0432\u0443\u043c\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438   | If Expr (CodeBlock Expr) (CodeBlock Expr)  -- if - \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438 \u0434\u0432\u0435 \u0432\u0435\u0442\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f   deriving (Eq, Ord, Show)<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u0438\u043b\u0438 \u0441\u0430\u043c\u044b\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 (\u0441\u043c. \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0432 \u043a\u043e\u0434\u0435). \u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0434\u043e\u043f\u043e\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; <code>ExprType<\/code>, <code>CodeBlock<\/code>. \u041f\u0435\u0440\u0432\u044b\u0439 &#8212; \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e &#171;enum&#187; \u0441 \u0442\u0438\u043f\u0430\u043c\u0438, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439. \u0421\u0435\u0439\u0447\u0430\u0441 \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u044b \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0437\u0430\u0434\u0435\u043b \u043d\u0430 \u0431\u0443\u0434\u0443\u0449\u0435\u0435 \u0438 \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445:<\/p>\n<pre><code class=\"haskell\">data ExprType   = VoidType   | IntType   | FloatType   | BytesType   | BooleanType   | CallableType [ExprType] ExprType  -- [\u0442\u0438\u043f\u044b \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432] \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f   | AutoType  -- \u0442\u0438\u043f \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0432\u044b\u0432\u0435\u0434\u0435\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438   deriving (Eq, Ord)<\/code><\/pre>\n<p><code>CodeBlock<\/code> &#8212; \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u043a:<\/p>\n<pre><code class=\"haskell\">type CodeBlock term = [term] -- [expr1, expr2] \u044d\u0442\u043e CodeBlock Expr<\/code><\/pre>\n<p>\u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u043c\u0435\u0436\u0434\u0443 \u0442\u0438\u043f\u0430\u043c\u0438 <code>[Expr]<\/code> \u0438 <code>CodeBlock Expr<\/code> \u0447\u0438\u0441\u0442\u043e \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u0430\u044f &#8212; <code>CodeBlock<\/code> \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0442\u0430\u043c, \u0433\u0434\u0435 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\u0442\u0435\u043b\u043e\u043c&#187; \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e (\u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0446\u0438\u043a\u043b\u0430 \u0438 \u043f\u0440.), \u0430 <code>[Expr]<\/code> &#8212; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043a \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0414\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0436\u0435 &#171;\u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e&#187; \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0442\u0438\u043f <code>AST<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-385926","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/385926","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=385926"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/385926\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=385926"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=385926"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=385926"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}