{"id":373550,"date":"2024-05-21T05:38:48","date_gmt":"2024-05-21T05:38:48","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=373550"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=373550","title":{"rendered":"<span>\u041e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b. \u0427\u0430\u0441\u0442\u044c 3\/3. \u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432<\/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<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9fd\/694\/7f9\/9fd6947f9e45ea48d968de46412704ac.png\" alt=\"\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u043c \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430!\" title=\"\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u043c \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430!\" width=\"1024\" height=\"762\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9fd\/694\/7f9\/9fd6947f9e45ea48d968de46412704ac.png\"\/><\/p>\n<div><figcaption>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u043c \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430!<\/figcaption><\/div>\n<\/figure>\n<p><a class=\"anchor\" name=\"container_programming\" id=\"container_programming\"><\/a><\/p>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043e\u0431\u0437\u043e\u0440\u0430 \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e, \u043a\u0430\u043a \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0424\u041f-\u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u201c\u0447\u0438\u0441\u0442\u043e\u0433\u043e\u201d \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u201c\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445\u201d \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c. \u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u0430 \u0440\u043e\u043b\u044c \u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u0432 \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043d\u0430\u0434 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u0437\u043e\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/\" rel=\"noopener noreferrer nofollow\">\u0427\u0430\u0441\u0442\u044c 1<\/a><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/#generic_types\" rel=\"noopener noreferrer nofollow\">\u041e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/#type_constructors\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0442\u0438\u043f\u043e\u0432<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/#polymorphic_types\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0435 \u0442\u0438\u043f\u044b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/#higher_tyeps\" rel=\"noopener noreferrer nofollow\">\u0422\u0438\u043f\u044b \u0432\u044b\u0441\u043e\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807485\" rel=\"noopener noreferrer nofollow\">\u0427\u0430\u0441\u0442\u044c 2<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807485\/#type_classes\" rel=\"noopener noreferrer nofollow\">\u041a\u043b\u0430\u0441\u0441\u044b \u0442\u0438\u043f\u043e\u0432<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807485\/#container_types\" rel=\"noopener noreferrer nofollow\">\u0422\u0438\u043f\u044b-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0427\u0430\u0441\u0442\u044c 3 (\u0434\u0430\u043d\u043d\u0430\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f) <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807495\/#container_programming\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u043a\u0430\u043a \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807495\/#subcategories_of_types\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0442\u0438\u043f\u043e\u0432 (\u0432\u043c\u0435\u0441\u0442\u043e \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f)<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p><a href=\"#container_programming\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u043a\u0430\u043a \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#traditioal_di\" rel=\"noopener noreferrer nofollow\">\u0422\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#reader\" rel=\"noopener noreferrer nofollow\">\u201c\u0427\u0438\u0442\u0430\u0442\u0435\u043b\u044c\u201d<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#free\" rel=\"noopener noreferrer nofollow\">\u0421\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#continuations\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0438 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#tagless_final\" rel=\"noopener noreferrer nofollow\">Tagless Final<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#arrows\" rel=\"noopener noreferrer nofollow\">\u041a\u043b\u0435\u0439\u0441\u043b\u0438 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0442\u0440\u0435\u0301\u043b\u043a\u0438<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#subcategories_of_types\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0442\u0438\u043f\u043e\u0432 (\u0432\u043c\u0435\u0441\u0442\u043e \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f)<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<h3>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u043a\u0430\u043a \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/h3>\n<p>\u0421\u043b\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u0435\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u0438 \u043f\u043e\u043c\u0435\u043d\u044c\u0448\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, \u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435 \u0442\u0430\u043a\u0438\u0435 <em>\u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435<\/em> \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0447\u0430\u0441\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u201c\u0430\u043b\u0433\u0435\u0431\u0440\u0430\u043c\u0438\u201d. \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 (\u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0432\u0441\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b) \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041d\u043e, \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0438\u0445 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p><a class=\"anchor\" name=\"traditioal_di\" id=\"traditioal_di\"><\/a><\/p>\n<h4>\u0422\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434<\/h4>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u0441\u0430\u043c\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0445 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043a\u043e\u0433\u0434\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u201c\u0432 \u043b\u043e\u0431\u201d \u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445. \u0422\u0435\u0440\u043c\u0438\u043d \u201c\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u201d \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u0435\u043d \u2013 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u201c\u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f\u201d \u0438\u0437 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043f\u0440\u0438\u0447\u0451\u043c, \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e, \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0444\u0430\u0439\u043b\u0435, \u0431\u0435\u0437 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u043a \u0446\u0435\u043b\u0435\u0432\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443.<\/p>\n<p>\u041f\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u201c\u0441\u0435\u0440\u0432\u0438\u0441\u044b\u201d \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u0438, \u0438 \u0438\u0445 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445-\u043e\u0434\u0438\u043d\u043e\u0447\u043a\u0430\u0445, \u043d\u0435 \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u044f\u0441\u044c \u043e \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u042d\u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438\u0434\u0435\u0435 \u201c\u043e\u0442\u043a\u0430\u0437\u0430 \u043e\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439\u201d, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u043a\u0430\u043a \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u0430 \u043d\u0435 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435. \u041d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0442 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435 \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0430\u0440\u0443\u0448\u0430\u0435\u0442 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u201c<a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%B8%D0%BD%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B8_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B5%D0%B9\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0432\u0435\u0440\u0441\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/a>\u201d, \u0432\u043d\u043e\u0441\u044f \u0432 \u043a\u043e\u0434 \u0438\u0437\u043b\u0438\u0448\u043d\u044e\u044e \u0441\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u044e \u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0436\u043d\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430 \u201c<a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%BE%D1%82%D0%BA%D1%80%D1%8B%D1%82%D0%BE%D1%81%D1%82%D0%B8\/%D0%B7%D0%B0%D0%BA%D1%80%D1%8B%D1%82%D0%BE%D1%81%D1%82%D0%B8\" rel=\"noopener noreferrer nofollow\">\u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438\/\u0437\u0430\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438<\/a>\u201d \u0438, \u043a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435, \u0438\u0437\u0434\u0435\u0440\u0436\u043a\u0430\u043c \u0432 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<p>\u0412 \u041e\u041e\u041f \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u0442\u043e\u043d\u043e\u043c \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0432 \u0432\u0438\u0434\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (<code>trait<\/code> \u0432 Scala), \u043a\u043b\u0430\u0441\u0441\u044b-\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0441\u0432\u043e\u0451\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435:<\/p>\n<pre><code class=\"scala\">trait Service1 { def func1(d: Double): Int    } trait Service2 { def func2(i: Int)   : String } trait Service3 { def func3(d: Double): String }  \/\/ \"\u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044f\" \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 final case class Service3Impl(srv1: Service1, srv2: Service2) extends Service3:   override def func3(d: Double) = srv2.func2(srv1.func1(d))<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Service3<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 <code>func1<\/code> \u0438 <code>func2<\/code> \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 <code>Service1<\/code> \u0438 <code>Service2<\/code>. \u041d\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u0442\u0443 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e <em>\u0441\u043f\u0435\u0440\u0432\u0430<\/em> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/p>\n<pre><code class=\"scala\">val srv1: Service1 = ??? val srv2: Service2 = ???  val srv3: Service3 = Service3Impl(srv1, srv2) srv3.func3(4.2)<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0439 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0435\u0439 \u0442\u0430\u043a\u043e\u0439 \u043d\u0430\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u201c\u0432\u0441\u043a\u0438\u043f\u0430\u043d\u0438\u044e\u201d \u043a\u043e\u0434\u0430 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438. \u0412 Scala \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/github.com\/softwaremill\/macwire\" rel=\"noopener noreferrer nofollow\">MacWire<\/a> \u2013 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442 \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0438\u0449\u0443\u0442 \u0438 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432\u0434\u0440\u0443\u0433 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430, \u043e\u0431 \u044d\u0442\u043e\u043c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<p>\u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <a href=\"https:\/\/habr.com\/ru\/articles\/350708\/#start_DI_containers\" rel=\"noopener noreferrer nofollow\"><em>DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432<\/em><\/a> (dependency injection container). \u0422\u0443\u0434\u0430 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u044b-\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0430 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u043d\u0430 <em>\u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e \u0442\u0438\u043f\u0443<\/em> \u043a\u0430\u043a\u043e\u0433\u043e-\u043b\u0438\u0431\u043e \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441\u0430\u043c \u0441\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u0443\u0435\u0442 \u044d\u0442\u043e\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0441\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 (\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u044d\u0442\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0438 \u0442.\u043f.). \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u043c\u043d\u043e\u0433\u0438\u0445 DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0436\u0438\u0437\u043d\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443, \u0438\u043b\u0438 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u0437 \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438. \u0422\u0430\u043a\u0436\u0435 \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0437\u0430\u0449\u0438\u0449\u0430\u044e\u0442 \u043e\u0442 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u0432\u0441\u0435\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f <em>\u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/em>. \u0417\u043d\u0430\u0447\u0438\u0442 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438, \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c.<\/p>\n<p>\u0412 Scala \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c <em>\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438<\/em>. \u041c\u0435\u0445\u0430\u043d\u0438\u0437\u043c <em>\u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0435\u0440\u043c\u043e\u0432<\/em> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044f\u0432\u043d\u043e \u0438\u043b\u0438 \u043d\u0435\u044f\u0432\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430:<\/p>\n<pre><code class=\"scala\">given Service1 = new Service1 { override def func1(d: Double) = ??? } given Service2 = new Service2 { override def func2(i: Int   ) = ??? }  object Service3:    def instance(using srv1: Service1, srv2: Service2) = Service3Impl(srv1, srv2)  Service3.instance.func3(4.2)<\/code><\/pre>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u0435 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u043a <code>instance<\/code> \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0439\u0434\u0435\u043d\u044b \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0438 \u043d\u0435\u044f\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u043a\u0430\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 <code>Service1<\/code> \u0438 <code>Service2<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u044d\u0442\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c <code>using<\/code>. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043f\u043e \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 <code>instance<\/code> \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432, \u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432\u044b\u0434\u0430\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u2013 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u044f\u0437\u044b\u043a\u0430 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u043f\u0440\u0438\u0447\u0451\u043c \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432!<\/p>\n<details class=\"spoiler\">\n<summary>Cake pattern<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u0442\u0435\u0445\u043d\u0438\u043a\u0438, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0442\u0438\u043f\u0430\u0445, \u043d\u043e \u0440\u0430\u0434\u0438 \u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u0441\u0442\u043e\u0438\u0442 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0443\u044e \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/www.baeldung.com\/scala\/cake-pattern\" rel=\"noopener noreferrer nofollow\">Cake pattern<\/a>. \u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u0442\u0440\u0435\u0439\u0442\u044b \u0441 \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438, \u0430 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044f \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0442\u0435\u043c\u0438 \u0441\u0430\u043c\u044b\u043c\u0438 \u0442\u0440\u0435\u0439\u0442\u0430\u043c\u0438. Cake-pattern \u0431\u0430\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0435 \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u0432, \u043d\u043e \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u043e\u0431 \u044d\u0442\u043e\u043c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0438\u043c\u0435\u0435\u0442 \u0440\u044f\u0434 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432 (\u0441\u043c., \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0442\u0430\u0442\u044c\u044e <a href=\"https:\/\/kubuszok.com\/2018\/cake-antipattern\/\" rel=\"noopener noreferrer nofollow\">Cake antipattern<\/a>), \u0438 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f.<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0443\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0448\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0438\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u0422\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u044b\u0448\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u043c, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u201c\u0447\u0438\u0441\u0442\u0430\u044f\u201d \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u044d\u0444\u0444\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0442.\u043f. \u0422\u0443\u0442 \u0432\u044b\u0440\u0443\u0447\u0430\u044e\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438.<\/p>\n<p>\u0412 Scala \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u044f\u0432\u043b\u044f\u043b\u0441\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 <code>Future<\/code>. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u0442\u043e\u043a\u0430\u043c, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0441\u043d\u0438\u0436\u0430\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430. \u041d\u043e \u0435\u0433\u043e \u201c\u0436\u0430\u0434\u043d\u044b\u0439\u201d \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440 \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u042d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043c\u043e\u0433\u0443\u0442 \u0440\u0435\u0448\u0438\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u201c\u043b\u0435\u043d\u0438\u0432\u044b\u0435\u201d \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u043a\u0430\u043a <code>IO<\/code> \u0438\u0437 <a href=\"https:\/\/typelevel.org\/cats\/\" rel=\"noopener noreferrer nofollow\">Cats<\/a>, <code>ZIO<\/code> \u0438\u0437 <a href=\"https:\/\/zio.dev\/\" rel=\"noopener noreferrer nofollow\">\u043e\u0434\u043d\u043e\u0438\u043c\u0451\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/a>, <code>Task<\/code> \u0438\u0437 \u0447\u0443\u0442\u044c \u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/monix.io\/\" rel=\"noopener noreferrer nofollow\">Monix<\/a>.<\/p>\n<p>\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u043e\u0441\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u044b \u0442\u0430\u043a\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0440\u0430\u043d\u0435\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0447\u0430\u0441\u0442\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u0430\u0445 \u0442\u0438\u043f\u043e\u0432, \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u0442\u0430\u043a\u0438\u0445:<\/p>\n<pre><code class=\"scala\">type Functor    [F[_]] = [A, B] =>  (A =>   B)  => (F[A] => F[B]) \/\/ Lift type Applicative[F[_]] = [A, B] => F[A =>   B]  => (F[A] => F[B]) \/\/ Lift &amp; Zip2 type Monad      [F[_]] = [A, B] =>  (A => F[B]) => (F[A] => F[B]) \/\/ Lift &amp; Flatten<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0445\u043e\u0436\u0435\u0441\u0442\u044c \u044d\u0442\u0438\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u0430\u0446\u0435\u043b\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0438\u0445 \u043d\u0430 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0451\u043d\u043d\u044b\u043c \u043e\u0434\u043d\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c <code>F[_]<\/code>. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, <code>Applicative<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a <code>Monad<\/code> \u2013 \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435. \u042d\u0442\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c <code>Monad<\/code> \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0432\u044b\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0443, \u0438 \u0441\u0431\u043e\u0439 \u0432 \u043b\u044e\u0431\u043e\u043c \u0437\u0432\u0435\u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u0442 \u043a \u0435\u0451 \u0440\u0430\u0437\u0440\u044b\u0432\u0443, \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044b. \u0412\u043e\u0442 \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430 \u0431\u0430\u0437\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>IO<\/code>:<\/p>\n<pre><code class=\"scala\">import cats.effect.IO import cats.syntax.all.* \/\/                                                \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0448\u0430\u0433\u043e\u0432 \u043d\u0435 \u0432\u0430\u0436\u043d\u044b def findTheKeys:        Clue          => IO[Keys]  = ??? def obtainPart1:        Keys          => IO[Part1] = ??? def obtainPart2:        Keys          => IO[Part2] = ??? def completeThePuzzle: (Part1, Part2) => Treasure  = ???  def findTheTreasure(someClue: Clue) =   findTheKeys(someClue)     .flatMap(keys => obtainPart1(keys) product obtainPart2(keys))      .map(completeThePuzzle.tupled)<\/code><\/pre>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0442\u0438\u043f\u043e\u0432 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>IO<\/code>:<\/p>\n<ul>\n<li>\n<p><code>map<\/code> <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\Leftarrow\" alt=\"\\Leftarrow\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0ac\/8c0\/031\/0ac8c003165f363e984ab1b08bee3653.svg\" width=\"19\" height=\"14\"\/> <code>Functor<\/code>,<\/p>\n<\/li>\n<li>\n<p><code>product<\/code> <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\Leftarrow\" alt=\"\\Leftarrow\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a9e\/631\/488\/a9e6314888ef10c75f1f625c08ae185e.svg\" width=\"19\" height=\"14\"\/> <code>Applicative<\/code>,<\/p>\n<\/li>\n<li>\n<p><code>flatMap<\/code> <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\Leftarrow\" alt=\"\\Leftarrow\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/973\/c80\/b27\/973c80b277042ac2158f953e5652b7c7.svg\" width=\"19\" height=\"14\"\/> <code>Monad<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e\u0442 \u0431\u043e\u043b\u0435\u0435 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>for<\/code>-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"scala\">def findTheTreasure(someClue: Clue) =   for {     keys  &lt;- findTheKeys(someClue)     part1 &lt;- obtainPart1(keys)     part2 &lt;- obtainPart2(keys)   } yield completeThePuzzle(part1, part2)<\/code><\/pre>\n<p><code>For<\/code>-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u201c\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0430\u0445\u0430\u0440\u201d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u0435\u0434\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0442\u0435\u0445 \u0436\u0435 <code>map<\/code>, <code>flatMap<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0437\u043e\u0432 <code>map<\/code> \u0441\u043f\u0440\u044f\u0442\u0430\u043d \u0437\u0434\u0435\u0441\u044c \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u0435 \u0441 <code>yield<\/code>, \u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 <code>Applicative<\/code> \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u044b \u2013 \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 <code>flatMap<\/code> \u0438, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0443\u0434\u0430\u0441\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <code>part1<\/code>, \u0442\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 <code>part2<\/code> \u0434\u0430\u0436\u0435 \u043d\u0435 \u043d\u0430\u0447\u043d\u0451\u0442\u0441\u044f.<\/p>\n<p>\u041a\u0430\u043a\u043e\u0439 \u0431\u044b \u0441\u0442\u0438\u043b\u044c \u043d\u0438 \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d, \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0441\u0443\u0442\u044c \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0435\u0439 \u2013 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u043d\u044a\u0435\u043a\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f (\u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e, \u043d\u0435\u044f\u0432\u043d\u043e) \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0432 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 (\u0438, \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u0447\u0438\u0441\u0442\u043e\u0439!) \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0435\u0440\u043c\u043e\u0432 \u0434\u043b\u044f \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 <code>Future\/IO<\/code>\/<code>ZIO<\/code>\/<code>Task<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f Scala-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0438, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0435 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439. \u0414\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432.<\/p>\n<p><a class=\"anchor\" name=\"reader\" id=\"reader\"><\/a><\/p>\n<h4>\u201c\u0427\u0438\u0442\u0430\u0442\u0435\u043b\u044c\u201d<\/h4>\n<p>\u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0438\u0445 \u0432 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u043c, \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044e\u0449\u0438\u043c\u0441\u044f \u0432\u043e \u0432\u0441\u0435\u0445 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u043d\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f, \u0430 <em>\u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u0432\u043e\u0437\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430<\/em>, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0435 \u0441\u0442\u043e\u0438\u043b\u043e \u0431\u044b \u0430\u043a\u0446\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435. \u0410 \u0432\u0435\u0434\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u041e\u041f\u041f-\u0448\u043d\u043e\u0439 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u043a\u043e\u0433\u0434\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0442\u0441\u044f \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c <em>\u043f\u0435\u0440\u0435\u0434<\/em> \u0438\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c. \u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0432\u0441\u044e \u0432\u043e\u0437\u043d\u044e \u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438 \u0432 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u043d\u0435\u0446 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u201c\u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c\u201d (reader).<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430 \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043a \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044e \u201c\u0438\u0437\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u201d, \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u043e\u043c\u0443 \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438. \u0412\u043e\u0442 \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0439 \u041e\u041e\u041f-\u0448\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c:<\/p>\n<pre><code class=\"scala\">trait Dep final case class ServiceImpl(dep: Dep):   def func(d: Double): String = ???<\/code><\/pre>\n<p>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c <code>dep: Dep<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0435\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u0418\u043d\u0430\u0447\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, \u043a\u043b\u0430\u0441\u0441 \u2013 \u044d\u0442\u043e \u043b\u0438\u0448\u044c \u043d\u0430\u0431\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 <em>\u0441\u043f\u0435\u0440\u0432\u0430<\/em> \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043a\u0430\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0412\u044b\u0440\u0430\u0437\u0438\u043c \u044d\u0442\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u044f\u0432\u043d\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0451\u043c \u043f\u0430\u0440\u0443 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439:<\/p>\n<pre><code class=\"scala\">def func_1(dep: Dep)(d: Double)    =  ??? \/\/  \u21d3\u21d3\u21d3\u21d3\u21d3\u21d3 \u0432\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0438\u0437\u043e\u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430 \u0442\u0438\u043f\u043e\u0432 (A\u1d2e)\u1d30 \u2261 (A\u1d30)\u1d2e def func_2(d: Double)(dep: Dep)    =  ??? \/\/  \u21d3\u21d3\u21d3\u21d3\u21d3\u21d3 \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c func_2 def func_3(d: Double) = (dep: Dep) => ???<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>func_3<\/code>, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>Double<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <em>\u0434\u0440\u0443\u0433\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e<\/em> \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>Dep<\/code>. \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>func_3<\/code> <em>\u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/em> <code>Dep<\/code>:<\/p>\n<pre><code class=\"scala\">val packedRes = func_3(4.2)  \/\/ Dep => Srting<\/code><\/pre>\n<p>\u0418 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"scala\">val dep = new Dep{} val finalRes = packedRes(dep) \/\/ String<\/code><\/pre>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0430\u0441\u044c, \u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0438\u0437\u043e\u043c\u043e\u0440\u0444\u0438\u0437\u043c\u043e\u0432 \u0442\u0438\u043f\u043e\u0432 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u0443\u044e \u0440\u0430\u043d\u0435\u0435 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044e \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0432 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u043d\u0435\u0446!<\/p>\n<p>\u0412\u044b\u0440\u0430\u0437\u0438\u043c \u044f\u0432\u043d\u043e \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 <code>func_3<\/code>:<\/p>\n<pre><code class=\"scala\">type Reader[D] = [A] =>> D => A type ReaderDep[A] = Reader[Dep][A] def func_3(d: Double): ReaderDep[String] = ???<\/code><\/pre>\n<p>\u041e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0439 \u0442\u0438\u043f <code>Reader<\/code> \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u0442\u0438\u043f\u0435 Scala, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u043c \u043f\u043e \u0442\u0438\u043f\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430. \u0414\u043b\u044f \u043d\u0435\u0433\u043e \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u201c\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435\u201d \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 <code>map<\/code>, <code>flatMap<\/code>, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u043e\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432\u0438\u0434\u0430 <code>func_3<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 <code>ReaderDep[_]<\/code>.<\/p>\n<p>\u0422\u0438\u043f <code>Reader<\/code> \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439. \u041d\u043e \u0442\u0443\u0442 \u0432\u044b\u0440\u0443\u0447\u0430\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u043d\u0451\u043c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440:<\/p>\n<pre><code class=\"scala\">type ReaderT[F[_], D] = [A] =>> Reader[D][F[A]] \/\/ D => F[A]<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <code>F[_]<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u0435\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, \u0430 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 \u043d\u0430\u0434 \u043d\u0438\u043c \u0442\u0440\u0430\u043d\u0441\u043b\u0438\u0440\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>\u0412 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Cats \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d \u0442\u0438\u043f <code>ReaderT<\/code>. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0440\u0435\u0431\u0443\u044e\u0442, \u0447\u0442\u043e\u0431\u044b \u0443 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0431\u044b\u043b\u0438 \u201c\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u201d \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u0442\u0438\u043f\u0430 (\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0448\u0435 \u044d\u0442\u043e <code>trait Dep<\/code>). \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f (\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f) \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043e\u0431\u0449\u0438\u0439 \u0442\u0438\u043f, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0449\u0438\u0439 \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u0438 \u043d\u0430 \u044d\u0442\u043e\u0439 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0441\u0432\u043e\u0439:<\/p>\n<pre><code class=\"scala\">import cats.data.ReaderT                    \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 import cats.effect.IO                       \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u044d\u0444\u0444\u0435\u0442\u043e\u0432  trait Dep1; trait Dep2                      \/\/ \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 type TotalDep = Dep1 &amp; Dep2                 \/\/ \u043e\u0431\u0449\u0430\u044f \"\u0436\u0438\u0440\u043d\u0430\u044f\" \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0435\u0438 \u0442\u0438\u043f\u043e\u0432 type ReaderIO[A] = ReaderT[IO, TotalDep, A] \/\/ \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440<\/code><\/pre>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0440\u0443\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u201c\u0436\u0438\u0440\u043d\u043e\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u201d \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043e\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u201c\u043d\u0430\u0441\u043b\u043e\u0435\u043d\u0438\u0435\u201d <code>ReaderT<\/code>, \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0442\u043e\u0447\u043d\u043e \u0441\u043e\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0432\u0442\u043e\u0440\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 ZIO. \u041a\u0430\u043a \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, \u043e\u0434\u043d\u043e\u0438\u043c\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u0430 <code>ReaderT<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 <code>Dep1<\/code> \u0438 <code>Dep1<\/code>:<\/p>\n<pre><code class=\"scala\">def func(d: Double) = for {   dep1 &lt;- ZIO.service[Dep1]   dep2 &lt;- ZIO.service[Dep2] } yield (??? : String) \/\/ \u0442\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f d, dep1, dep2<\/code><\/pre>\n<p>\u0415\u0451 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443:<\/p>\n<pre><code class=\"scala\">val packedRes = func(4.2) \/\/ ZIO[Dep1 &amp; Dep2, Nothing, String]<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0438 \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c <code>ReaderT<\/code>, \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c:<\/p>\n<pre><code class=\"scala\">val dep1Layer = ZLayer.succeed(new Dep1{})  val dep2Layer = ZLayer.succeed(new Dep2{})  val zioRes = packedRes.provide(dep2Layer, dep1Layer) \/\/ ZIO[Any, Nothing, String]<\/code><\/pre>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>zioRes<\/code> \u0443\u0436\u0435 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u043e\u043d\u043e \u043b\u0438\u0448\u044c \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 <code>cats.IO[_]<\/code>.<\/p>\n<p>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b <em>\u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435<\/em> \u0438 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u201c\u0421\u043b\u043e\u0438\u201d (layers) \u043d\u0430\u043c\u0435\u043a\u0430\u044e\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0448\u0430\u0431\u043b\u043e\u043d \u201c\u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c\u201d \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043d\u0430 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u044d\u0442\u0430\u043f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439. \u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435  \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u0439 \u044d\u0442\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u0421\u0442\u043e\u0438\u0442 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0442\u0430\u043a\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u0442\u0430\u043f \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u201c\u0447\u0438\u0441\u0442\u044b\u043c\u201d, \u0431\u0435\u0437 \u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432. \u0421\u0445\u043e\u0436\u0438\u043c\u0438 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0442 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u201c\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435\u201d \u043f\u043e\u0434\u0445\u043e\u0434\u044b, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043b\u0435\u0435 \u2013 \u0441\u043f\u0435\u0440\u0432\u0430 \u0438\u0434\u0451\u0442 \u201c\u0447\u0438\u0441\u0442\u043e\u0435\u201d \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u0438 \u043b\u0438\u0448\u044c \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u0438 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p><a class=\"anchor\" name=\"free\" id=\"free\"><\/a><\/p>\n<h4>\u0421\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440<\/h4>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0439 \u0442\u0438\u043f:<\/p>\n<pre><code class=\"scala\">enum Freee[F[_], A]:   case Pure   [F[_], A](a: A)              extends Freee[F, A]   case Suspend[F[_], A](a: F[Freee[F, A]]) extends Freee[F, A]<\/code><\/pre>\n<p>\u0423\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0438\u043f\u044b <code>Freee[F, A]<\/code> \u0438 <code>F[A]<\/code> \u0438\u0437\u043e\u043c\u043e\u0440\u0444\u043d\u044b \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 <code>A<\/code> \u0438 \u043a\u043e\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043d\u043e\u0433\u043e <code>F[+_]<\/code>. \u0414\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f, \u043a\u0430\u043a \u0438 \u0441\u0430\u043c\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e <em>\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0433\u043e<\/em> \u0442\u0438\u043f\u0430 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u0437\u0443\u0447\u0438\u043c \u043b\u0438\u0448\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430.<\/p>\n<p>\u0418\u043c\u0435\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c <code>map<\/code> \u0434\u043b\u044f <code>F[_]<\/code>, \u043c\u043e\u0436\u0435\u043c &#171;\u043f\u043e\u0434\u043d\u044f\u0442\u044c&#187; \u0435\u0451 \u0438 \u0434\u043e <code>Freee<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432 <code>enum<\/code>:<\/p>\n<pre><code class=\"scala\">def map[B](f: A => B)(using Lift[F]): Freee[F, B] = this match \/\/ this: Freee[F, A] - \u043c\u044b \u0436\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 enum   case Pure(a)     => Pure(f(a))   case Suspend(fa) => Suspend(fa.map(_.map(f)))<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 <code>Lift<\/code>, \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0439 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u043d\u0435\u0435 \u2013 \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>map<\/code> \u0434\u043b\u044f <code>fa<\/code> \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u0435.<\/p>\n<p>\u041d\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u0442\u043e, \u043a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u201c\u0440\u0430\u0437\u043c\u0435\u0442\u0440\u0451\u0448\u0438\u0432\u0430\u043d\u0438\u0435\u201d <code>Freee<\/code>:<\/p>\n<pre><code class=\"scala\">import Freee.* extension [F[_]: Lift, A](ffa: Freee[F, Freee[F, A]])   def flatten: Freee[F, A] = ffa match     case Pure(fa) => fa     case Suspend(a) => Suspend(a.map(_.flatten))<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>F[_]<\/code> \u0432\u0440\u043e\u0434\u0435 <code>flatten<\/code>, \u0438\u043b\u0438 <code>flatmap<\/code> \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0442\u043e, \u0432\u0432\u0438\u0434\u0443 \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0437\u043e\u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430 \u0441 <code>F[_]<\/code>, <code>Freee<\/code> <em>\u043e\u0431\u043e\u0433\u0430\u0449\u0430\u0435\u0442<\/em> \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u201c\u0440\u0430\u0437\u043c\u0430\u0442\u0440\u0451\u0448\u0438\u0432\u0430\u043d\u0438\u044f\u201d!<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0434\u0430\u043b\u0435\u0435, \u0430 \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u0441\u044f \u043e\u0442 \u043d\u0430\u0437\u043e\u0439\u043b\u0438\u0432\u043e\u0433\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f <code>F[_]: Lift<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c <code>Freee<\/code>. \u041e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432 \u0442\u0438\u043f-\u0441\u0443\u043c\u043c\u0443 <code>Freee<\/code> \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u043e \u0441\u043b\u0430\u0433\u0430\u0435\u043c\u043e\u0435, \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u201c\u0431\u043e\u043b\u0435\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439\u201c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <code>Freer<\/code>:<\/p>\n<pre><code class=\"scala\">enum Freer[F[_], A]:   case Pure   [F[_], A](a: A)                                      extends Freer[F, A]   case Suspend[F[_], A](a: F[Freer[F, A]])                         extends Freer[F, A]   case FlatMap[F[_], A, B](fb: Freer[F, B], afb: B => Freer[F, A]) extends Freer[F, A]  import Freer.*  extension [F[_], A](ffa: Freer[F, A])   def map[B](f: A => B): Freer[F, B] = FlatMap(ffa, f andThen Pure.apply)   def flatMap[B](f: A => Freer[F, B]): Freer[F, B] = FlatMap(ffa, f)  extension [F[_], A](ffa: Freer[F, Freer[F, A]])   def flatten: Freer[F, A] = FlatMap(ffa, identity)<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0441 \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u0435\u043c \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 <code>F<\/code>, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0434\u0430\u0436\u0435 \u043d\u0435 \u043e\u0436\u0438\u0434\u0430\u044f, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438! \u0420\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0443 <code>Freer<\/code> \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"scala\">extension [F[_], A](ffa: Freer[F, A])   def go(extract: [X] => F[Freer[F, X]] => Freer[F, X])(using Lift[F]): A =     ffa match       case Pure(fa)         => fa       case Suspend(ffa)     => extract(ffa) go extract       case FlatMap(fb, bfa) => bfa(fb go extract) go extract<\/code><\/pre>\n<p>\u0412 \u0447\u0451\u043c \u0436\u0435 \u0432\u044b\u0433\u043e\u0434\u0430, \u0435\u0441\u043b\u0438 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438 <code>Freer<\/code> \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 <code>F<\/code>? \u0425\u0438\u0442\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u043e\u0436\u043d\u043e \u0432 \u0441\u043e\u0432\u0441\u0435\u043c \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440! \u0422\u0430\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>foldMap<\/code> \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>G[_]<\/code>; \u043f\u043e\u0437\u0430\u0438\u043c\u0441\u0442\u0432\u0443\u0435\u043c \u0438\u0445 \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 \u0442\u0438\u043f\u043e\u0432 <code>cats.Monad<\/code>:<\/p>\n<pre><code class=\"scala\">import cats.Monad import cats.syntax.all.*  extension [F[_], A](ffa: Freer[F, A])   def foldMap[G[_]: Monad](fToG: F ~> G): G[A] = ffa match     case Return(a)      => Monad[G].pure(a)                            \/\/ pure    \u0438\u0437 Monad[G]     case Suspend(ma)    => fToG(ma).flatMap(_ foldMap fToG)            \/\/ flatMap \u0438\u0437 Monad[G]     case FlatMap(fa, f) => fa.foldMap(fToG).flatMap(f(_) foldMap fToG) \/\/ flatMap \u0438\u0437 Monad[G]<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u043e\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043d\u0430 <code>F[_]<\/code> \u2013 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <em>\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435<\/em> \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0431\u0438\u0437\u043d\u0435\u0441-\u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432. \u041e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043b\u0438\u0448\u044c \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u201c\u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435\u201c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>~><\/code> \u0438\u0437 \u044d\u0442\u0438\u0445 \u0431\u0438\u0437\u043d\u0435\u0441<strong>\u043e<\/strong>\u0432\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0432 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0435, \u0432\u0440\u043e\u0434\u0435 <code>IO<\/code>. \u041a\u043b\u0430\u0441\u0441 <code>Free[F[_], _]<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440, \u043d\u043e \u0435\u0433\u043e \u043d\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u201c\u043c\u043e\u043d\u0430\u0434\u043d\u044b\u043c\u201d, \u043a\u0430\u043a \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0438\u0437 \u0440\u0430\u0437\u0434\u0435\u043b\u0430 \u0432\u044b\u0448\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>F[_]<\/code> \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <em>\u043b\u044e\u0431\u043e\u0439<\/em> \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u0434\u0430\u0436\u0435 \u0431\u0435\u0437 \u044f\u0432\u043d\u044b\u0445 \u201c\u043c\u043e\u043d\u0430\u0434\u043d\u044b\u0445\u201d \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u0432\u0440\u043e\u0434\u0435 <code>flatMap<\/code> \u2013 \u0432\u043e\u043e\u0431\u0449\u0435 <em>\u043d\u0438\u043a\u0430\u043a\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043d\u0435 \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f<\/em>!<\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u201c\u0431\u043e\u043b\u0435\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e\u201d \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>Freer<\/code> \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Cats \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c <a href=\"https:\/\/typelevel.org\/cats\/datatypes\/freemonad.html\" rel=\"noopener noreferrer nofollow\">Free<\/a>. \u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0442\u0430\u043a\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 (\u0447\u0438\u0441\u0442\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f):<\/p>\n<pre><code class=\"scala\">val initVal: Future[Int] = Future.successful(21) def effectiveFunc(i: Int)(using ExecutionContext): Future[Int] =   Future {     val intRes = i * 2     println(s\"$i => $intRes\")     intRes   }<\/code><\/pre>\n<p>\u0421\u043e\u0431\u0435\u0440\u0451\u043c \u0438\u0437 \u043d\u0438\u0445 \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u201c\u043f\u043e\u0434\u043d\u044f\u0432\u201d \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <code>Future[_]<\/code>, \u0432 \u201c\u043c\u0438\u0440\u201d \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>Free[Future, _]<\/code> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Cats \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>Free.liftF<\/code>:<\/p>\n<pre><code class=\"scala\">val freeInitVal       = Free.liftF(initVal)              \/\/ \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 val freeEffectiveFunc = effectiveFunc andThen Free.liftF \/\/ \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e (\u0443 liftF \u0435\u0441\u0442\u044c \u043d\u0443\u0436\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430) def buildFreeProgram(using ExecutionContext): Free[Future, Int] =   freeInitVal     .flatMap(freeEffectiveFunc)     .flatMap(freeEffectiveFunc) \/\/ \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e-\u043f\u0440\u0438\u043a\u043e\u043b\u0443, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u0443 \u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0435\u0449\u0451 \u0440\u0430\u0437<\/code><\/pre>\n<p>\u0414\u043b\u044f <code>Free<\/code> \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e \u201c\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445\u201d \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0438 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0438\u0439 \u043e\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>Future<\/code> . \u041e\u043d\u0438 \u043f\u0440\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u043f\u043e\u0437\u0434\u043d\u0435\u0435, \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>freeProgram<\/code> \u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0430 \u201c\u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0430\u201d \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>def go(f: S[Free[S, A]] => Free[S, A])(implicit S: Functor[S]): A<\/code>:<\/p>\n<pre><code class=\"scala\">given ExecutionContext = ExecutionContext.global import cats.instances.future.catsStdInstancesForFuture \/\/ \u0438\u043c\u043f\u043e\u0440\u0442 \u043d\u0435\u044f\u0432\u043d\u043e\u0433\u043e Functor[Future]  def extractFuture[A]: Future[A] => A =   Await.result(_, Duration.Inf)  val freeProgram = buildFreeProgram \/\/ \"\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u0443\u0435\u043c\" \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443  \/\/ \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0435\u0451 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 (\u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0443) \u0434\u0432\u0430\u0436\u0434\u044b: val res1 = freeProgram go extractFuture \/\/ (using Functor[Future]), \u0442\u0430\u043a \u043a\u0430\u043a \"\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c\" \u043d\u0443\u0436\u0435\u043d map val res2 = freeProgram go extractFuture \/\/ (using Functor[Future]), \u0442\u0430\u043a \u043a\u0430\u043a \"\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c\" \u043d\u0443\u0436\u0435\u043d map print(res1, res2)<\/code><\/pre>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u0442 \u043a \u0442\u0430\u043a\u043e\u043c\u0443 \u0432\u044b\u0432\u043e\u0434\u0443 \u043d\u0430 \u043a\u043e\u043d\u0441\u043e\u043b\u044c:<\/p>\n<pre><code>21 => 42 42 => 84 21 => 42 42 => 84 (84,84)<\/code><\/pre>\n<p>\u041d\u0435 \u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <code>Future<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u201c\u0436\u0430\u0434\u043d\u044b\u043c\u201d, \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432 <code>Free<\/code> \u0434\u0430\u0451\u0442 \u201c\u043b\u0435\u043d\u0438\u0432\u044b\u0439\u201d \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043a\u0430\u043a \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 <code>IO<\/code> \u2013 \u0432\u0441\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u0430\u043f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438. \u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b (\u0432\u044b\u0432\u043e\u0434 \u043d\u0430 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u0442\u0440\u043e\u0447\u0435\u043a \u0432\u0438\u0434\u0430 <code>x => y<\/code>) \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0434\u0432\u0430\u0436\u0434\u044b \u2013 \u043f\u0440\u0438 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0435 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 <code>res1<\/code> \u0438 <code>res2<\/code>. \u0414\u043b\u044f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438 <code>Free<\/code> \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 <em>\u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e<\/em> \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0448\u0435 \u044d\u0442\u043e <code>extractFuture: Future[A] => A<\/code> \u0438 <code>map<\/code> \u0438\u0437 \u043d\u0435\u044f\u0432\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0442\u0438\u043f\u0430 <code>Functor[Future]<\/code>, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0433\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 Cats.<\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435\u043d \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 <code>foldMap<\/code>:<\/p>\n<pre><code class=\"scala\">def extractFuture[A]: Future[A] => A =   Await.result(_, Duration.Inf)  val interpreter: Future ~> Id =           \/\/ \"\u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435\" \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432   FunctionK.lift{ [X] => (fx: Future[X]) => extractFuture(fx) }  val res = freeProgram foldMap interpreter \/\/ \u043d\u0435\u044f\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Monad[Id] \u0434\u043b\u044f flatMap, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 println(res)                              \/\/ \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043b\u0435\u043d\u0438\u0432\u043e\u0439 \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u043e\u0439 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u0430 <code>Free<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u044b\u0439 \u0442\u0440\u044e\u043a \u0434\u043b\u044f \u0434\u0435\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438. \u0420\u0430\u043d\u0435\u0435 \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u043c \u0442\u0438\u043f\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0442\u0435 \u0438\u043b\u0438 \u0438\u043d\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b. \u042d\u0444\u0444\u0435\u043a\u0442\u044b \u0437\u0430\u0432\u044f\u0437\u0430\u043d\u044b \u043d\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 (\u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u043b\u044f \u0438 \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u044b \u0432 \u043f\u0430\u043c\u044f\u0442\u0438), \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0435\u0433\u043e \u201c\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439\u201d \u2013 \u0437\u0430\u043f\u0430\u043a\u043e\u0432\u043a\u0438, \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439, \u043f\u0435\u0440\u0435\u043f\u0430\u043a\u043e\u0432\u043a\u0438 \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0438, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438. \u042d\u0442\u043e \u0434\u0430\u0451\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u0438\u0442\u044c <em>\u0447\u0438\u0441\u0442\u0443\u044e \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439<\/em>. \u041d\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 <code>Free<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u0442\u043e\u0433\u043e \u0436\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u0442\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0437\u0430\u0434\u0430\u043d\u044b \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e, \u0430 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b. \u0418\u0445, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438 <code>Free<\/code>, \u043d\u043e \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u043c. \u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, <strong>\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432<\/strong>.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044d\u0442\u0438 \u0442\u0438\u043f\u044b<\/p>\n<pre><code class=\"scala\">type UserId    = Int type UserInfo  = String type UserSaved = Unit<\/code><\/pre>\n<p>\u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/p>\n<pre><code class=\"scala\">type GetUser = UserId => Option[UserInfo] type PutUser = (UserId, UserInfo) => UserSaved type ListAll = Unit => List[(UserId, UserInfo)]<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u201c\u0447\u0438\u0441\u0442\u044b\u043c\u0438\u201d, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441 \u0438\u0437\u043c\u0435\u043d\u0447\u0438\u0432\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u2013 \u044d\u0442\u043e \u201c\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435\u201d \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0427\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0445 \u201c\u0447\u0438\u0441\u0442\u044b\u043c\u0438\u201d, \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435, \u0447\u044c\u044f \u201c\u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0430\u201d \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0430 \u0431\u044b \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432. \u0422\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u0442\u0430\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u0445 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u043e\u0433\u043e \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430:<\/p>\n<pre><code class=\"scala\">enum UsersRepository[A]:   case Get(id: UserId)                 extends UsersRepository[Option[UserInfo]]   case Put(id: UserId, user: UserInfo) extends UsersRepository[UserSaved]   case ListAll                         extends UsersRepository[List[(UserId, UserInfo)]]<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0439 \u0442\u0438\u043f <code>UsersRepository[_]<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u043c, \u043d\u043e \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0435\u044f\u0432\u043d\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0431\u0435 \u043e\u0442 \u0441\u0432\u043e\u0438\u0445 \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u0432-\u0441\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u0445. \u041e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u0435\u043c <em>\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0430<\/em>.<\/p>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0447\u0430\u0441\u0442\u043e \u0432\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441\u0432\u043e\u0435\u0433\u043e \u0440\u043e\u0434\u0430 <em>\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 <s>\u043c\u0443\u0441\u043e\u0440<\/s> \u0441\u0430\u0445\u0430\u0440<\/em>:<\/p>\n<pre><code class=\"scala\">import UsersRepository.* type FreeUsersRepo[X] = Free[UsersRepository, Option[UserInfo]] \/\/ \u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 def liftUserRepo = cats.free.Free.liftK[UsersRepository]        \/\/ UsersRepository ~> FreeUsersRepo  def getUser(id: UserId)                : FreeUsersRepo[Option[UserInfo]] = liftUserRepo(Get(id)) def putUser(id: UserId)(user: UserInfo): FreeUsersRepo[Unit]             = liftUserRepo(Put(id, user)) def listUsers                          : FreeUsersRepo[List[UserInfo]]   = liftUserRepo(ListAll)<\/code><\/pre>\n<p>\u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0442\u0438\u043f\u043e\u0432 \u0438\u0437\u043b\u0438\u0448\u043d\u0438. \u041e\u043d\u0438 \u043b\u0438\u0448\u044c \u043f\u043e\u0434\u0447\u0451\u0440\u043a\u0438\u0432\u0430\u044e\u0442, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 <em>\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u043c<\/em> \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u043d\u0430\u0434 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c <code>UsersRepository<\/code>. \u0418\u0437 \u044d\u0442\u0438\u0445 \u201c\u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0451\u043d\u043d\u044b\u0445\u201d \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438:<\/p>\n<pre><code class=\"scala\">import cats.syntax.all.* val program = \/\/ FreeUsersRepo[List[(UserId, UserInfo)]]   putUser(42)(\"answer\") >>   listUsers<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c <code>>><\/code> \u2013 \u044d\u0442\u043e \u043b\u0438\u0448\u044c \u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c \u0438\u0437 Cats \u0434\u043b\u044f <code>flatMap<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 (\u201c\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432\u201d, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u201c\u043f\u0440\u0430\u0432\u044b\u0439\u201c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442). \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>program<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0441 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c \u0435\u0449\u0451 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u043c. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u201c\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u201d, \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a <em>\u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/em> \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <code>UsersRepository<\/code>, \u043a\u0430\u043a \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043a \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443 \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432:<\/p>\n<pre><code class=\"scala\">import cats.arrow.FunctionK.{lift as liftTransform} import cats.{Id, ~>} import scala.collection.mutable.{Map as MutMap}  val usersRepoInterpreter: UsersRepository ~> Id = {   val storage = MutMap.empty[UserId, UserInfo]   liftTransform{[A] => (fa: UsersRepository[A]) =>     {fa match       case Get(id)       => storage.get(id)       case Put(id, user) => storage.addOne(id, user)       case ListAll       => storage.toList     }.asInstanceOf[A] \/\/ \u0430 \u0432\u0435\u0434\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0438 \u0441\u0430\u043c \u043c\u043e\u0433 \u0431\u044b \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f...   } }  program foldMap usersRepoInterpreter \/\/ List((24,rewsna), (42,answer))<\/code><\/pre>\n<p>\u0417\u0434\u043e\u0440\u043e\u0432\u043e! \u041d\u043e \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0449\u0451 \u0442\u0430\u043a\u0438\u0435:<\/p>\n<pre><code class=\"scala\">enum SearchServcie[A]:   case SearchBest (request: String) extends DataServcie[String]   case FindSeveral(request: String) extends DataServcie[List[(Relevance, String)]]  enum NotificationService[A]:   case Send(notification: String) extends NotificationService[NotificationResult]<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u201c\u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c\u201d \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0447\u0435\u0442\u0430\u043b \u0431\u044b \u0432\u0441\u0435 \u044d\u0442\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u044b. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Cats \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0442\u0438\u043f <a href=\"https:\/\/typelevel.org\/cats\/api\/cats\/data\/EitherK.html\" rel=\"noopener noreferrer nofollow\">EitherK<\/a> \u0432\u0438\u0434\u0430 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"(\\star\\Rightarrow\\star,\\;\\star\\Rightarrow\\star,\\;\\star)\\Rightarrow\\star\" alt=\"(\\star\\Rightarrow\\star,\\;\\star\\Rightarrow\\star,\\;\\star)\\Rightarrow\\star\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cee\/f75\/ca0\/ceef75ca04807d3e9ce2d9081d741769.svg\" width=\"191\" height=\"22\"\/>. \u042d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u043d\u043e \u0438\u0445 <em>\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440<\/em>. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432:<\/p>\n<pre><code class=\"scala\">import cats.data.EitherK type :+:[F[_], G[_]] = [A] =>> EitherK[F, G, A] \/\/ \u043b\u0435\u0432\u043e-\u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430\u0434 \u0442\u0438\u043f\u0430\u043c\u0438-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438 type TotalAlgebra[A] = (   UsersRepository     :+:   SearchServcie       :+:   NotificationService )[A]<\/code><\/pre>\n<p>\u041b\u0435\u0432\u043e-\u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b, \u0432\u0440\u043e\u0434\u0435 \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0433\u043e \u0442\u0443\u0442 <code>:+:<\/code> \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043b\u044e\u0448\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0432 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e <a href=\"https:\/\/github.com\/ProjectSeptemberInc\/freek\/tree\/master\" rel=\"noopener noreferrer nofollow\">Freek<\/a>.<\/p>\n<p>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u0432\u044b\u0448\u0435 <code>TotalAlgebra<\/code>, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u201c\u0430\u043b\u0433\u0435\u0431\u0440\u0430\u043c\u0438\u201d \u043d\u0430\u0434 \u0442\u0438\u043f\u043e\u043c-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e, \u043a\u0430\u043a \u0438 \u0432 \u0430\u043a\u0430\u0434\u0435\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0435, \u043e\u043d\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 N-\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0442\u0438\u043f\u0430-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 (\u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430).<\/p>\n<p>\u201c\u0421\u0430\u0445\u0430\u0440\u043d\u044b\u0435\u201d \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c \u0434\u043e <code>TotalAlgebra<\/code>:<\/p>\n<pre><code class=\"scala\">import SearchServcie.* import NotificationService.*  def liftF = cats.free.Free.liftInject[TotalAlgebra]  def searchBest      (request: String)            = liftF(SearchBest (request)) def findSeveral     (request: String)            = liftF(FindSeveral(request)) def sendNotification(notification: Notification) = liftF(Send(notification))<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f <code>UsersRepository<\/code>. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>liftInject<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0435\u044f\u0432\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0442\u0438\u043f\u0430 <code>InjectK[Big[_], Small[_]]<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043f\u043e \u0441\u0443\u0442\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u201c\u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435\u201d \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>Small<\/code> \u043a <code>Big<\/code>. \u0412 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Cats \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u044f\u0432\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>InjectK<\/code> \u0441 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u043c <code>or<\/code> \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c <code>EitherK<\/code>.<\/p>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0432 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e <code>usersRepoInterpreter<\/code> \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u044b <code>dataServcieInterpreter<\/code> <code>notificationInterpreter<\/code> \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>or<\/code> (\u0432\u0430\u0436\u043d\u043e \u0441\u043e\u0431\u043b\u044e\u0441\u0442\u0438 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0432 <code>TotalAlgebra<\/code>):<\/p>\n<pre><code class=\"scala\">def searchServcieInterpreter: SearchServcie       ~> Id = \/\/ \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f def notificationInterpreter : NotificationService ~> Id = \/\/ \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f  extension[F[_], G[_]](fg: F ~> G)   def :+:[H[_]]      (hg: H ~> G) = fg or hg \/\/ \u043b\u0435\u0432\u043e-\u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0438\u043d\u043e\u043d\u0438\u043c \u0434\u043b\u044f or  def totalInterpreter =   usersRepoInterpreter     :+:   searchServcieInterpreter :+:   notificationInterpreter<\/code><\/pre>\n<p>\u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0443\u0436\u0435 \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u0435 <em>\u0431\u043e\u043b\u044c\u0448\u0438\u0435<\/em> \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b ?:<\/p>\n<pre><code class=\"scala\">val littleBigProgram =   searchBest(\"best user\")           productL   sendNotification(\"user captured\") flatMap   putUser(42)                       productR   getUser(42)                       map   {_.fold(\"\")(_.reverse)}           flatMap \/\/ \u043f\u0435\u0440\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u0422\u0438\u043f\u0430, \u0442\u0430\u043a \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a \u0437\u0430\u0445\u043e\u0442\u0435\u043b)))   putUser(24)                       productR   listUsers  littleBigProgram foldMap totalInterpreter<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0430\u044f \u0442\u0435\u0445\u043d\u0438\u043a\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430 \u0442\u0435\u043c, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c <em>\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b-\u043a\u0430\u043a-\u0434\u0430\u043d\u043d\u044b\u0435<\/em>. \u0415\u0434\u0438\u043d\u043e\u0436\u0434\u044b \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438. \u041f\u043e\u043c\u0438\u043c\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0432 <code>Id<\/code>, \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438 \u0431\u044b\u0432\u0430\u044e\u0442 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432  <code>Either<\/code> (\u0434\u043b\u044f \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432), \u0438\u043b\u0438 \u0432\u0441\u044f\u043a\u0438\u0435 <code>Future<\/code> (\u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435) <code>IO<\/code>, <code>ZIO<\/code> (\u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430). \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0432\u0441\u0451 \u0436\u0435 \u0442\u0430\u043a\u0430\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c <code>Free<\/code> \u0440\u0435\u0434\u043a\u043e \u0431\u044b\u0432\u0430\u0435\u0442 \u0432\u043e\u0441\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u043d\u043e\u0439. \u041e\u0434\u043d\u0430\u043a\u043e, \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u043a\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043d\u043e \u0438 \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 <a href=\"https:\/\/tpolecat.github.io\/doobie\/\" rel=\"noopener noreferrer nofollow\">doobie<\/a> \u0435\u0441\u0442\u044c <code>type ConnectionIO[A]\u00a0=\u00a0Free[ConnectionOp,\u00a0A]<\/code> \u2013 \u043d\u0430\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430\u0434 <code>ConnectionOp<\/code>, \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u043e\u0439 \u0441\u0443\u043c\u043e\u0439 \u0442\u0438\u043f\u043e\u0432, \u043e\u043b\u0438\u0446\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 JDBC-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0412\u043e\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u0442\u0443\u0440\u044b \u043e\u0431 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>Free<\/code>.<\/p>\n<ul>\n<li>\n<p>\u0420\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0430 \u0425\u0430\u0431\u0440\u0435: <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/655089\/\" rel=\"noopener noreferrer nofollow\">Scala: \u0413\u0435\u043a\u0441\u0430\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0438 DDD \u043d\u0430 Free Monad \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438<\/a> \u041c\u0443\u0445\u0430\u043c\u043c\u0430\u0434\u0430 \u0417\u0443\u043d\u0443\u043d\u043e\u0432\u0430.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/254715\/\" rel=\"noopener noreferrer nofollow\">\u0427\u0435\u043c \u0445\u043e\u0440\u043e\u0448\u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0435 \u043c\u043e\u043d\u0430\u0434\u044b<\/a> \u2013 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0430\u0442\u044c\u0438 \u0413\u0430\u0431\u0440\u0438\u0435\u043b\u043b\u044b \u0413\u043e\u043d\u0441\u0430\u043b\u0435\u0441 (Haskell).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0410\u043d\u0433\u043b\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/nrinaudo.github.io\/articles\/free_monad.html\" rel=\"noopener noreferrer nofollow\">The debatably Free monad<\/a> \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>Free<\/code> \u043e\u0442 \u041d\u0438\u043a\u043e\u043b\u044f \u0420\u0438\u043d\u0430\u0443\u0434\u043e.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/blog.rockthejvm.com\/free-monad\/\" rel=\"noopener noreferrer nofollow\">Free Monad in Scala<\/a> \u0414\u0430\u043d\u0438\u044d\u043b\u044f \u0427\u043e\u043a\u044b\u0440\u043b\u0430\u043d\u0430 \u0441 \u0435\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430 <a href=\"https:\/\/rockthejvm.com\/\" rel=\"noopener noreferrer nofollow\">Rock the JVM!<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/softwaremill.com\/free-monads\/\" rel=\"noopener noreferrer nofollow\">Free monads &#8212; what? and why?<\/a> \u0410\u0434\u0430\u043c\u0430 \u0412\u0430\u0440\u0441\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/underscore.io\/blog\/posts\/2015\/04\/14\/free-monads-are-simple.html\" rel=\"noopener noreferrer nofollow\">Free Monads Are Simple<\/a> \u041d\u043e\u044d\u043b\u044f \u0412\u0435\u043b\u0448\u0430.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0422\u0438\u043f <code>Free[F[_], _]<\/code> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Cats: <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/typelevel.org\/cats\/datatypes\/freemonad.html\" rel=\"noopener noreferrer nofollow\">Free Monad<\/a> \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435 Type Level;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/eed3si9n.com\/herding-cats\/Free-monads.html\" rel=\"noopener noreferrer nofollow\">Free monads<\/a> \u0441 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 <em>herding cats<\/em> \u042e\u0434\u0436\u0438\u043d\u0430 \u0419\u043e\u043a\u043e\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u201c\u0411\u043e\u043b\u0435\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439\u201d \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 Freer: <\/p>\n<ul>\n<li>\n<p>\u0441\u0442\u0430\u0442\u044c\u044f \u041e\u043b\u0435\u0433\u0430 \u041a\u0438\u0441\u0435\u043b\u0451\u0432\u0430 \u0438 \u0425\u0438\u0440\u043e\u043c\u0438 \u0418\u0448\u0438\u0438 <a href=\"https:\/\/okmij.org\/ftp\/Haskell\/extensible\/more.pdf\" rel=\"noopener noreferrer nofollow\">Freer Monads, More Extensible Effects<\/a>;<\/p>\n<\/li>\n<li>\n<p>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/atnos-org.github.io\/eff\/\" rel=\"noopener noreferrer nofollow\">eff<\/a> \u2013 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0442\u0430\u043c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 <code>Eff<\/code>, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435  \u043e\u0442 <code>Free<\/code> \u0438\u0437 Cats, \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0431\u043e\u0440\u043a\u0438 \u043e\u0431\u0449\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430 \u2013 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u201c\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0439\u201d \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043f\u0440\u0438\u0447\u0451\u043c \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435;<\/p>\n<\/li>\n<li>\n<p>\u043e\u0442\u0432\u0435\u0442 \u043d\u0430 Stackoverflow <a href=\"https:\/\/stackoverflow.com\/questions\/45039766\/different-between-eff-monad-and-free-monad\" rel=\"noopener noreferrer nofollow\">Different between Eff monad and Free monad<\/a>;<\/p>\n<\/li>\n<li>\n<p><a href=\"http:\/\/mandubian.com\/2015\/04\/09\/freer\/\" rel=\"noopener noreferrer nofollow\">FreeR &#8212; Hybrid Free Monads for Reduced Quadratic Complexity\/Observability &amp; Map-Fusion Optimization in Scala<\/a> &#8212; \u0441\u0442\u0430\u0442\u044c\u044f \u0432 \u0431\u043b\u043e\u0433\u0435 \u041f\u0430\u0441\u043a\u0430\u043b\u044f \u0412\u043e\u0439\u0442\u043e;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/halcat.org\/scala\/extensible\/index.html#freer-monad\" rel=\"noopener noreferrer nofollow\">Extensible Effects in Scala<\/a> \u2013 \u0441\u0442\u0430\u0442\u044c\u044f \u0438\u0437 \u0431\u043b\u043e\u0433\u0430 \u0421\u0430\u043d\u0448\u0438\u0440\u043e \u0419\u043e\u0448\u0438\u0434\u044b (\u0442\u0443\u0442 \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u044f\u043f\u043e\u043d\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435\u2026 \u0438\u043b\u0438 \u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f Google-\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a\u043e\u043c).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"continuations\" id=\"continuations\"><\/a><\/p>\n<h4>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0438 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b<\/h4>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0443\u0436\u0435 \u043d\u0435\u043e\u0434\u043d\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0442\u0438\u043f\u044b \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438, \u0442\u0435\u043c, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0438\u043c\u0435\u044f \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f. \u0418 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0442\u0438\u043f\u043e\u0432 \u0432\u0430\u0436\u043d\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 <em>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/em>. \u041d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u044d\u0442\u0443 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0427\u0451\u0440\u0447\u0430. \u0422\u0438\u043f\u044b \u0432 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435 \u0427\u0451\u0440\u0447\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u044b <strong>\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f<\/strong> \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0437\u0443\u0435\u043c\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u044d\u0442\u0438\u0445 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u0438\u0439 \u0442\u0438\u043f <code>Type1<\/code>. \u0414\u043b\u044f \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430\u0431\u043e\u0440 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0432\u0438\u0434\u0430 <code>Type1 => A<\/code> <em>\u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445<\/em> \u0442\u0438\u043f\u043e\u0432 <code>A<\/code>. <em>\u042d\u043a\u0437\u0438\u0441\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439<\/em> \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440 \u044d\u0442\u043e\u0433\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f (\u201c<em>\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442<\/em> \u0442\u0430\u043a\u0438\u0435 \u0442\u0438\u043f\u044b <code>A<\/code>, \u0447\u0442\u043e\u2026\u201c), \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 <em>\u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0439<\/em> \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435:<\/p>\n<pre><code class=\"scala\">type Type2 = [A] => (Type1 => A) => A<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0438\u043f \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u0439 \u043d\u0430 \u0432\u0445\u043e\u0434 <em>\u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f<\/em> \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 <code>Type1<\/code>. \u0422\u0438\u043f\u044b <code>Type1<\/code> \u0438 <code>Type2<\/code> \u0438\u0437\u043e\u043c\u043e\u0440\u0444\u043d\u044b: \u0438\u0437 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0431\u0430\u0437 \u043f\u043e\u0442\u0435\u0440\u0438 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<pre><code class=\"scala\">val \u0442\u0443\u0434\u0430:    Type1 => Type2 = (v: Type1) => [A] => (f: Type1 => A) => f(v) val \u043e\u0431\u0440\u0430\u0442\u043d\u043e: Type2 => Type1 = (v: Type2) => v(identity)  assert((\u0442\u0443\u0434\u0430    andThen \u043e\u0431\u0440\u0430\u0442\u043d\u043e)(t1) == t1) \/\/ \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 t1: Type1 assert((\u043e\u0431\u0440\u0430\u0442\u043d\u043e andThen \u0442\u0443\u0434\u0430   )(t2) == t2) \/\/ \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 t2: Type2<\/code><\/pre>\n<p>\u0418 \u0432\u0441\u0451 \u0436\u0435 <code>Type1<\/code> \u0438 <code>Type2<\/code> \u043d\u0435 \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b \u2013 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0434\u0430\u0451\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b, \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u043e\u0439 \u0447\u0435\u0440\u0442\u043e\u0439 \u043e\u0441\u043e\u0431\u043e\u0433\u043e <em>\u0441\u0442\u0438\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439<\/em> (continuation passing style \u2013 CPS). \u042d\u0442\u043e \u0442\u0438\u043f\u044b-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u0431\u0443\u0434\u0443\u0442 <em>\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u044b<\/em> \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u201c\u0445\u0440\u0430\u043d\u0438\u043c\u043e\u0433\u043e\u201d \u0442\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412 CPS \u0432\u044b\u0437\u043e\u0432\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tail_call\" rel=\"noopener noreferrer nofollow\">\u0445\u0432\u043e\u0441\u0442\u043e\u0432\u044b\u043c\u0438<\/a>. \u0415\u0441\u043b\u0438 \u044f\u0437\u044b\u043a \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 <a href=\"https:\/\/stackoverflow.com\/questions\/310974\/what-is-tail-call-optimization\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u044b\u0445 \u0432\u044b\u0437\u043e\u0432<\/a> (TCO \u2013 tail call optimization), \u0442\u043e \u0432 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0438 \u0441 CPS \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0434\u0430\u0442\u044c \u043f\u0440\u0438\u0440\u043e\u0441\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0412 Scala \u0435\u0441\u0442\u044c <a href=\"https:\/\/www.baeldung.com\/scala\/tail-recursion\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u043e\u0439 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438<\/a> (\u0447\u0430\u0441\u0442\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 TCO) \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 CPS-\u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u0432\u0435\u0441\u044c\u043c\u0430 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 <em>\u043a\u043e\u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438<\/em> \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>F[_]<\/code> \u0438\u0437\u043e\u043c\u043e\u0440\u0444\u0435\u043d \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443:<\/p>\n<pre><code class=\"scala\">type Codensity = [F[_]] =>> [A] =>> [B] => (A => F[B]) => F[B]<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043d\u0435\u0433\u043e \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"scala\">trait Monad[F[_]]: \/\/ \u0432\u0430\u0436\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438   val pure:    [A]    => A => F[A]   val lift:    [A, B] => (A => B) => (F[A] => F[B])   val flatten: [A]    => F[F[A]] => F[A]   \/\/ map \u0438 flatMap \u0441\u0442\u0440\u043e\u044f\u0442\u0441\u044f \u0438\u0437 \u043d\u0438\u0445 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:   val map     = [A, B] => (f: A => B) => lift(f)   val flatMap = [A, B] => (afb: A => F[B]) => (fa: F[A]) => flatten(lift(afb)(fa))    given [F[_]]: Monad[Codensity[F]] with   val pure    = [A]    => (a: A) => [B] => (f: A => F[B]) => f(a)   val lift    = [A, B] => (ff: A => B) => (coda: Codensity[F][A])  => [C] => (f: B => F[C]) => coda(f compose ff)   val flatten = [A]    => (codCodA: Codensity[F][Codensity[F][A]]) => [B] => (f: A => F[B]) => codCodA(_ apply f)<\/code><\/pre>\n<p>\u041d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u0438 \u0434\u043b\u044f \u201c\u0431\u043e\u043b\u0435\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e\u201d \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u0430 <code>Freer<\/code>, \u043a\u043e\u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, <em>\u043d\u0435 \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044f \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440<\/em>. \u041d\u043e \u0447\u0442\u043e\u0431\u044b \u201c\u043f\u043e\u0434\u043d\u044f\u0442\u044c\u201d \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u201c\u043c\u0438\u0440\u0430\u201d <code>F[_]<\/code> \u0432 \u201c\u043c\u0438\u0440\u201d <code>Codensity[F]<\/code> \u0432\u0441\u0451 \u0436\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f <code>F[_]<\/code>:<\/p>\n<pre><code class=\"scala\">def rep[F[_]: Monad, A](fa: F[A]): Codensity[F][A] = \/\/ \u043d\u0435\u044f\u0432\u043d\u043e \u0442\u044f\u043d\u0443\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Monad[F]   [B] => (afb: A => F[B]) => summon[Monad[F]].flatMap(afb)(fa) \/\/ Monad[F].flatMap  given Monad[Option] with \/\/ \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f Option   val pure =    [A]    => (a: A) => Some(a)   val lift =    [A, B] => (f: A => B) => (coda: Option[A]) => coda map f   val flatten = [A]    => (optOptA: Option[Option[A]]) => optOptA.flatten  val codOptInt: Codensity[Option][Int] = rep(Some(42)) val optInt:              Option [Int] = codOptInt(Some.apply) \/\/ Some(42)<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 <code>Freer<\/code>, \u043a\u043e\u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u201c\u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c\u0441\u044f\u201d \u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 <code>F[_]<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e \u0432\u0437\u0430\u043c\u0435\u043d \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0435\u043f\u043b\u043e\u0445\u0443\u044e \u043a\u043e\u043c\u043f\u0435\u043d\u0441\u0430\u0446\u0438\u044e.<\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f <em>\u0440\u0435\u0441\u0443\u0440\u0441\u0430<\/em>, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0449\u0430\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0446\u0438\u043a\u043b \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439: <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\text{\u0437\u0430\u0445\u0432\u0430\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u0430}\\Rightarrow\\text{\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430}\\Rightarrow\\text{\u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430}.\" alt=\"\\text{\u0437\u0430\u0445\u0432\u0430\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u0430}\\Rightarrow\\text{\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430}\\Rightarrow\\text{\u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430}.\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/40b\/866\/6ac\/40b8666ac7b6eb12d600f2f6f8e9b72d.svg\" width=\"503\" height=\"21\"\/><\/p>\n<p>\u0412 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Cats \u0435\u0441\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 <a href=\"https:\/\/typelevel.org\/cats-effect\/docs\/std\/resource\" rel=\"noopener noreferrer nofollow\">Resource<\/a>, \u0441\u0443\u0442\u044c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439:<\/p>\n<pre><code class=\"scala\">type Resource = [F[_]] =>> [R] =>> (Unit => F[R], R => F[Unit]) => Codensity[F][R] \/\/                                 (    accure   ,   release  ) => use with continuation<\/code><\/pre>\n<p>\u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u0445\u0432\u0430\u0442\u0430 (accure) \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f (release) \u0440\u0435\u0441\u0443\u0440\u0441\u0430 <code>R<\/code>, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0443\u044e \u043d\u0430 \u0432\u0445\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f (use) \u0440\u0435\u0441\u0443\u0440\u0441\u0430, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0443\u044e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>\u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 <code>Codensity<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0447\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u043d\u0435\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0442\u0430\u043a\u0438\u043c \u0442\u0438\u043f\u043e\u043c. \u0427\u0430\u0449\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0438\u043f <code>ContT<\/code>, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u043e\u0439 \u0442\u0430\u043a\u0443\u044e \u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043d\u043e \u0443\u0436\u0435 \u043d\u0435 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u0443\u044e:<\/p>\n<pre><code class=\"scala\">type ContT     = [F[_], A, X] =>> (X => F[A]) => F[A] type Codensity = [F[_]] =>> [X] =>> [A] => ContT[F][A, X]<\/code><\/pre>\n<p>\u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 <code>ContT[F, A, X]<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 <code>X<\/code> \u0438 \u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u0421 \u0442\u0438\u043f\u043e\u043c <code>ContT<\/code> \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u043e\u0434\u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u0448\u043d\u043e\u0432\u0430\u0442\u043e\u0433\u043e \u0432\u0438\u0434\u0430:<\/p>\n<pre><code class=\"scala\">def callCC[F[_], A, X, Y]   : ((Y => ContT[F, A, X]) => ContT[F, A, Y]) => ContT[F, A, Y]   = f => yfa => f { y => _ => yfa(y) }(yfa)   \/\/                     \u2191\u2191\u2191\u2191\u2191\u2191\u2191\u2191\u2191\u2191\u2191 \u0438\u0433\u043e\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435!<\/code><\/pre>\n<p>\u042d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u201c\u0432\u044b\u0437\u043e\u0432\u0430 \u0441 \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435\u043c\u201d (<strong>call<\/strong> with <strong>c<\/strong>urrent <strong>c<\/strong>ontinuation \u2013 callCC) <a href=\"https:\/\/stackoverflow.com\/questions\/7178919\/how-to-make-callcc-more-dynamic\/7180154#7180154\" rel=\"noopener noreferrer nofollow\">\u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f<\/a> \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043b\u044f \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u0430 \u043a\u043e\u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0433\u0438\u0431\u043a\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u043e\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 <code>goto<\/code>, <code>try\/throw\/catch\/finally<\/code>, <code>async\/await<\/code> \u0438 \u0442.\u043f.<\/p>\n<p>\u0412 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 Cats \u0435\u0441\u0442\u044c <a href=\"https:\/\/typelevel.org\/cats\/datatypes\/contt.html\" rel=\"noopener noreferrer nofollow\">\u0441\u0432\u043e\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u0430 ContT<\/a>, \u0438 \u0442\u0430\u043c \u0443\u0436\u0435 <a href=\"https:\/\/www.javadoc.io\/static\/org.typelevel\/cats-docs_2.13\/2.10.0\/cats\/data\/ContT%24.html\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/a> \u043c\u0435\u0442\u043e\u0434 <code>callCC<\/code>. \u041d\u0430 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c <em>\u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f<\/em>:<\/p>\n<pre><code class=\"scala\">def getCC[M[_] : Defer : Monad, R, A]: ContT[M, R, ContT[M, R, A]] = {   ContT.callCC[M, R, ContT[M, R, A], A] { c =>     lazy val x: ContT[M, R, A] = ContT.later(c(x).run) \/\/ \u043b\u0435\u043d\u0438\u0432\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f!     ContT.pure(x)   } }<\/code><\/pre>\n<p>\u042d\u0442\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b \u041c\u0430\u0442\u0435\u0443\u0448 \u041a\u0443\u0431\u0443\u0436\u043e\u043a (\u0440\u0430\u043d\u0435\u0435 \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0438\u0441\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0438\u0437 \u0435\u0433\u043e \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e <a href=\"https:\/\/kubuszok.com\/\" rel=\"noopener noreferrer nofollow\">\u0431\u043b\u043e\u0433\u0430<\/a>), \u043f\u0443\u0442\u044c \u043a \u043d\u0435\u0439 \u043e\u043d \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043b \u0432 <a href=\"https:\/\/stackoverflow.com\/a\/78073145\/4583514\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u043c \u043e\u0442\u0432\u0435\u0442\u0435 \u043d\u0430 Stackoverflow<\/a>. \u041c\u0435\u0442\u043e\u0434 <code>getCC<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0424\u041f-\u0430\u043d\u0430\u043b\u043e\u0433 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 <code>goto<\/code>:<\/p>\n<pre><code class=\"scala\">def asksLoop =   for {     gotoLabel &lt;- getCC[IO, Unit, Unit]     _         &lt;- ContT.liftF(IO.println(\"\u0425\u043e\u0434\u0438\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c? [\u0434\/\u043d]\"))     answer    &lt;- ContT.liftF(IO.readLine)     _ &lt;-      if (answer == \"\u0434\") gotoLabel               else               ContT.liftF(IO.unit)   } yield ()  asksLoop.run(_ => IO.println(\"\u041f\u043e\u043a\u0430!\")).unsafeRunSync()<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u201c\u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430\u0437\u0430\u0434\u201c, \u043d\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u0438 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u0438 \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<p>\u0422\u0430\u043a \u0436\u0435, \u043f\u043e \u0441\u043b\u0435\u0434\u0430\u043c <a href=\"https:\/\/stackoverflow.com\/a\/6004732\/4583514\" rel=\"noopener noreferrer nofollow\">\u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 Stackoverflow<\/a>, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>callCC<\/code> \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a \u2013 \u0431\u0443\u0434\u0435\u043c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 0.<\/p>\n<pre><code class=\"scala\">\/\/ \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 def whenA[F[_], R](b: Boolean)(happyWay: ContT[F, R, Unit]) =   if (b) happyWay else ContT.pure(())  def div[R](x: Int, y: Int)(handler: String => ContT[IO, R, Int]): ContT[IO, R, Int] =   ContT.callCC((ok: Int => ContT[IO, R, String]) =>             \/\/ \"\u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u043e\u0435\" \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435     ContT.callCC((notOK: String => ContT[IO, R, Unit]) =>       \/\/ \"\u043d\u0435\u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u043e\u0435\" \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435       whenA(y == 0)(notOK(\"\u041d\u0435\u043b\u044c\u0437\u044f \u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430 0 \")) >> ok(x \/ y)  \/\/ \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435     ).flatMap(handler)                                          \/\/ \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \"\u043d\u0435\u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u043e\u0435\" \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c \u043f\u043e\u043a\u0430 \u043c\u0435\u0442\u043e\u0434\u043e\u043c   ) val calc1 = div[Unit](10, 2) \/\/ : (String => ContT[IO, Unit, Int]) => ContT[IO, Unit, Int] val calc2 = div[Unit](10, 0) \/\/ : (String => ContT[IO, Unit, Int]) => ContT[IO, Unit, Int]<\/code><\/pre>\n<p>\u0412 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 <code>calc1<\/code> \u0438 <code>calc2<\/code> \u043b\u0435\u0436\u0430\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0435 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0443, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0435\u2026 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435\u2026 \u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0442\u0430\u043a \u043d\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b, \u0430 \u0442\u0438\u043f\u044b \u0442\u0435\u0440\u043c\u043e\u0432 \u0432 \u043d\u0451\u043c \u0435\u0449\u0451 \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u041d\u043e \u043d\u0435 \u0432\u0441\u0451 \u0442\u0430\u043a \u043f\u043b\u043e\u0445\u043e ? \u2013 \u0434\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0443\u0442 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u0434\u0430 \u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0442\u0430\u043c \u043d\u0435 \u0442\u043e\u0440\u0447\u0430\u0442 \u043d\u0430\u0440\u0443\u0436\u0443. \u041f\u043e\u043a\u0430 \u0436\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f <em>\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/em> \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 0:<\/p>\n<pre><code class=\"scala\">def myErrorHandler(str: String) = ContT[IO, Unit, Int]{f => IO.print(str) >> f(42)} \/\/        \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u0443\u0435\u043c, \u043d\u043e \u0438 \u0412\u041e\u0421\u0421\u0422\u0410\u041d\u0410\u0412\u041b\u0418\u0412\u0410\u0415\u041c\u0421\u042f \u0441 \u043d\u0435\u043a\u0442\u043e\u0440\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u2191\u2191\u2191\u2191\u2191  \/\/ \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0449\u0438\u043a \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a myErrorHandler def myRun(calc: (String => ContT[IO, Unit, Int]) => ContT[IO, Unit, Int]) =    calc     .apply(myErrorHandler) \/\/ \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u044d\u0444\u0444\u0435\u043a\u0442\u0430     .run(IO.println(_))    \/\/ \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0430 ContT \u0432 IO     .unsafeRunSync()       \/\/ \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0430 IO (\u0432 Id)  myRun(calc1) \/\/ 5 myRun(calc2) \/\/ \u041d\u0435\u043b\u044c\u0437\u044f \u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430 0 42<\/code><\/pre>\n<p>\u0412 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0441\u0442\u0440\u043e\u0447\u043a\u0430\u043c \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0432\u044b\u0432\u043e\u0434 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c. \u0412\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043e\u0448\u0438\u0431\u043e\u043a \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>42<\/code> \u043e\u043d\u043e <em>\u0432\u0435\u0440\u043d\u0443\u043b\u043e\u0441\u044c \u0432 \u0442\u043e \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u0431\u044b\u043b\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430<\/em>!<\/p>\n<p>\u0421\u0442\u0438\u043b\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0445\u043e\u0436\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0448\u0438\u0431\u043a\u0438, \u043d\u043e \u0438 <em>\u043b\u044e\u0431\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b<\/em>. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 <code>callCC<\/code> \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u0438 \u201c\u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0435\u201d \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043f\u043e\u0434\u0432\u043e\u0434\u044f\u0442 \u043a \u0438\u0434\u0435\u0435 <strong>\u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432<\/strong>. \u042d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u043e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435, \u0442\u0430\u043a \u0438 \u0441\u0432\u043e\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b, \u043e\u0442\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044f \u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u044e \u043d\u0430 \u043a\u043e\u043d\u0435\u0446 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0412 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438, \u043a\u043e\u0433\u0434\u0430 <em>\u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e<\/em> \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0437\u043d\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0447\u0435\u043d\u044c \u0432\u0441\u0435\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u043a\u0438 \u201c\u0442\u043e\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e\u201d \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u043d\u0435 \u043e\u0431\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0432\u0441\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u043e\u0431\u0435\u0449\u0430\u044e\u0442 \u0432\u044b\u0438\u0433\u0440\u044b\u0448 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0414\u043b\u044f Scala \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0430\u043c\u0438. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0442\u0430\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u0434\u0430 \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u044d\u0442\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/b-studios.de\/scala-effekt\/\" rel=\"noopener noreferrer nofollow\">Scala Effekt<\/a> (\u043d\u0435 \u043f\u0443\u0442\u0430\u0442\u044c \u0441 Cats.Effect) \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 (\u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u043c\u0438) \u0442\u0440\u0435\u0439\u0442\u0430\u043c\u0438 \u0441 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 <code>Control<\/code> \u2013 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0440\u0430\u0437\u043d\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/marcinzh.github.io\/turbolift\/\" rel=\"noopener noreferrer nofollow\">Turbolift<\/a> \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0430\u043c\u0438, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0435 \u0441\u0430\u043c\u044b\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0432\u0440\u043e\u0434\u0435 <code>!!<\/code> \u0438\u043b\u0438 <code>!@!<\/code> (?) \u0438 \u0433\u043e\u0440\u0434\u0438\u0442\u0441\u044f \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/getkyo.io\/\" rel=\"noopener noreferrer nofollow\">Kyo<\/a> \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0430\u043c\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u201c\u0441\u0442\u0440\u0435\u043b\u043e\u043a\u201d <code>><\/code> \u0438 <code>&lt;<\/code> , \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0432\u043a\u0443\u0441\u043d\u044b\u0445 \u043f\u043b\u044e\u0448\u0435\u043a.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439 \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u043d\u0430\u0431\u0438\u0440\u0430\u044e\u0449\u0430\u044f \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u043c\u0430. \u0412 \u0430\u043d\u0433\u043b\u043e\u044f\u0437\u044b\u0447\u043d\u043e\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u0442\u0443\u0440\u0435 \u043e\u043d\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u201c<strong>Direct Style<\/strong>\u201d, \u0430 \u0432 \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u043e\u0439\u2026 \u0435\u0449\u0451 \u043d\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0430\u0441\u044c ?. \u0414\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u201c<em>\u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u0441\u0442\u0438\u043b\u0435\u043c<\/em>\u201d. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u201d\u043e\u0442\u043a\u0443\u0434\u0430 \u0434\u0443\u0435\u0442 \u0432\u0435\u0442\u0435\u0440\u201d.<\/p>\n<p>\u0420\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043c\u043d\u043e\u0433\u043e\u0437\u0430\u0434\u0430\u0447\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u0441\u0442\u0440\u0435\u043c\u043b\u0435\u043d\u0438\u0435 \u043a \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0432\u0435\u043b\u0430 \u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0432 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u044f\u0437\u044b\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0449\u0438\u0445 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u043d\u0430 C#:<\/p>\n<pre><code class=\"cs\">async Task&lt;int> CalcStep1(int v0) async Task&lt;int> CalcStep2(int v1)  async Task&lt;int> Calc(int v0) { var v1 = await CalcStep1(v0); return   await CalcStep2(v1); }<\/code><\/pre>\n<p>\u0421\u0432\u044f\u0437\u043a\u0430 <code>async\/await<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u043f\u043e\u043a\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f <code>CalcStep1<\/code> \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u0430: \u043e\u0442\u0432\u0435\u0442\u0430 web-\u0441\u043b\u0443\u0436\u0431\u044b \u0438 \u0442.\u043f. \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 (\u0442\u043e\u0447\u043d\u0435\u0435, \u043f\u043e\u0442\u043e\u043a, thread) \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0438 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u043a \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c\u0443, \u043b\u0438\u0448\u044c \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f. \u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u044d\u0442\u043e\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0430\u0445\u0430\u0440 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u0435\u0441\u044c\u043c\u0430 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 <em>\u043e\u0447\u0435\u043d\u044c \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u043e<\/em> \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">Task&lt;int> Calc(int v0) { return CalcStep1(v0) .ContinueWith(task1 => CalcStep2(task1.Result), TaskContinuationOptions.OnlyOnRanToCompletion) .Unwrap(); }<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>ContinueWith<\/code> \u0441\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c <code>TaskContinuationOptions.OnlyOnRanToCompletion<\/code> \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 <code>map<\/code>, \u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u0432 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u044f\u0432\u043d\u043e \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>Result<\/code> \u0443 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 <code>task1: Task&lt;int><\/code>. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043c\u0435\u0442\u043e\u0434 <code>Unwrap<\/code>, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 <code>Task&lt;Task&lt;int>><\/code> \u0432 <code>Task&lt;int><\/code>, \u0441\u0443\u0442\u044c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 <code>flatten<\/code>. \u0412\u044b\u0437\u043e\u0432 <code>ContinueWith<\/code> \u0432 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0438 \u0441 <code>Unwrap<\/code> \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0430\u043d\u0430\u043b\u043e\u0433 <code>flatMap<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0439 C#-\u0442\u0438\u043f <code>Task&lt;><\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438. \u0417\u043d\u0430\u0447\u0438\u0442 <code>async\/await<\/code> \u2013 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0443\u044e (direct) \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435!<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>ContinueWith<\/code> \u2013 \u044f\u0432\u043d\u044b\u0439 \u043d\u0430\u043c\u0451\u043a, \u0447\u0442\u043e \u043a\u043e\u0434 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u043d \u0432 \u0441\u0442\u0438\u043b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439. \u0412 <a href=\"https:\/\/stackoverflow.com\/a\/4071015\/4583514\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u043c \u043e\u0442\u0432\u0435\u0442\u0435 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441<\/a> \u043d\u0430 Stackoverflow, \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432 <code>await CalcStep1(v0)<\/code> \u043c\u043e\u0436\u043d\u043e <em>\u0441\u0438\u043c\u0432\u043e\u043b\u0438\u0447\u0435\u0441\u043a\u0438<\/em> \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e (\u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0432 C#) \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0430 <code>callCC<\/code> \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a<\/p>\n<pre><code class=\"cs\">callCC CalcStep1(v0).GetAwaiter().BeginAwait;<\/code><\/pre>\n<p>\u0412 Cats \u0435\u0441\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 <code>ContT<\/code> \u043d\u0430\u0434 \u043b\u044e\u0431\u044b\u043c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c, \u0438 \u0434\u0430\u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>callCC<\/code> \u043f\u0440\u0438 \u043d\u0451\u043c. \u0417\u043d\u0430\u0447\u0438\u0442, \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0439\u0442\u0438\u0441\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043b\u044e\u0431\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0432 <em>\u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435<\/em>, \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e <code>async\/await<\/code> \u0432 C#. \u0415\u0441\u0442\u044c, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, for-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043d\u043e \u0443 \u043d\u0438\u0445 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u0432\u0438\u0434\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/scala\/scala-async\" rel=\"noopener noreferrer nofollow\">scala-async<\/a> \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>Future<\/code>;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/typelevel.org\/cats-effect\/docs\/std\/async-await\" rel=\"noopener noreferrer nofollow\">cats-effect-cps<\/a> \u0434\u043b\u044f <code>IO<\/code>;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/zio\/zio-direct\" rel=\"noopener noreferrer nofollow\">zio-direct<\/a>, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0434\u043b\u044f <code>ZIO<\/code> (\u0442\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u044f\u0437\u043a\u0430 <code>defer\/run<\/code>);<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/lampepfl\/gears\" rel=\"noopener noreferrer nofollow\">gears<\/a> \u2013 \u201c\u0434\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438\u201d \u043e\u0442 <a href=\"https:\/\/www.epfl.ch\/labs\/lamp\/\" rel=\"noopener noreferrer nofollow\">\u0430\u0432\u0442\u043e\u0440\u043e\u0432<\/a> Scala 3;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/rssh.github.io\/dotty-cps-async\/\" rel=\"noopener noreferrer nofollow\">dotty-cps-async<\/a> \u2013 \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f Scala 3;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/monadless\/monadless\" rel=\"noopener noreferrer nofollow\">Monadless<\/a> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e <code>lift\/unlift<\/code>;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/ThoughtWorksInc\/each\" rel=\"noopener noreferrer nofollow\">Each<\/a> \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u043c\u0430\u043a\u0440\u043e-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043d\u043e \u0437\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0430\u0440\u0430 <code>monadic\/each<\/code>;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/xebia-functional\/Unwrapped\" rel=\"noopener noreferrer nofollow\">Unwrapped<\/a> \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0430 Scala 3, \u043f\u043e\u0445\u043e\u0436\u0435, \u0447\u0442\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u0430\u043a\u0440\u043e\u0441\u044b; \u0432\u043c\u0435\u0441\u0442\u043e <code>await<\/code> \u0442\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>bind<\/code>, \u0430 <code>async<\/code> \u0437\u0430\u043c\u0435\u0449\u0430\u044e\u0442 <a href=\"https:\/\/docs.scala-lang.org\/scala3\/reference\/contextual\/context-functions.html\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/a>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0438 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u043e\u0431\u0449\u0430\u044f \u0441\u0443\u0442\u044c. \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e \u043c\u043e\u0442\u0438\u0432\u0430\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/rssh.github.io\/dotty-cps-async\/\" rel=\"noopener noreferrer nofollow\">dotty-cps-async<\/a>:<\/p>\n<pre><code class=\"scala\">val c = async[F] {                                     \/\/ c: F[String]   val url     = \"http:\/\/www.example.com\"   val data    = await(api.fetchUrl(url))               \/\/ fetchUrl:         String          => F[String]   val theme   = api.classifyText(data)                 \/\/ classifyText:     String          =>   String   val dmpInfo = await(api.retrieveDMPInfo(url, theme)) \/\/ retrieveDMPInfo: (String, String) => F[String]   dmpInfo }<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b <code>fetchUrl<\/code> \u0438 <code>retrieveDMPInfo<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 <code>F<\/code> \u0438 \u0438\u0445 \u0432\u044b\u0437\u043e\u0432\u044b \u043e\u0431\u0451\u0440\u043d\u0443\u0442\u044b \u0432 <code>await<\/code>. \u042d\u0442\u043e \u043d\u0435 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0430, \u0430 \u043d\u0435\u043a\u0438\u0439 \u043c\u0430\u0440\u043a\u0435\u0440 \u0434\u043b\u044f \u043c\u0430\u043a\u0440\u043e\u0441\u0430 <code>async<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u0435\u043c\u0443 \u0431\u043b\u043e\u043a \u0432 \u0441\u0442\u0438\u043b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439. \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>= await<\/code> \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u0441\u0442\u0440\u0435\u043b\u043a\u0443 <code>&lt;-<\/code> \u0432 <code>for<\/code>-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438, \u043d\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0432\u0440\u043e\u0434\u0435 <code>if<\/code>, <code>return<\/code> (\u0440\u0430\u043d\u043d\u0438\u0439 \u0432\u044b\u0445\u043e\u0434), \u0438\u043b\u0438 \u0442\u043e\u0433\u043e \u0436\u0435 <code>for<\/code>. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043f\u043e\u0437\u0434\u043d\u0438\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/rssh.github.io\/dotty-cps-async\/AutomaticColoring.html\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c<\/a> <code>await<\/code>, \u0447\u0442\u043e \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u044f\u0432\u043b\u0435\u043d\u0438\u044f \u201c<a href=\"https:\/\/journal.stuffwithstuff.com\/2015\/02\/01\/what-color-is-your-function\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0437\u043d\u043e\u0446\u0432\u0435\u0442\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439<\/a>\u201d.<\/p>\n<p>\u041c\u0438\u043d\u0443\u0441\u044b \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0438\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439 \u0432 Scala \u0445\u043e\u0440\u043e\u0448\u043e <a href=\"https:\/\/stackoverflow.com\/questions\/78055394\/get-current-contiuation-in-scala?noredirect=1#comment137630265_78055394\" rel=\"noopener noreferrer nofollow\">\u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043b<\/a> \u041c\u0430\u0442\u0435\u0443\u0448 \u041a\u0443\u0431\u0443\u0436\u043e\u043a. \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 <code>ContT<\/code>, <code>Codensity<\/code> \u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u0441\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u043f\u0440\u044f\u0433\u0430\u044e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0432\u044b\u0432\u043e\u0434 \u0442\u0438\u043f\u043e\u0432 Scala, \u043d\u043e \u043e\u043d \u0432\u0441\u0451 \u0436\u0435 \u0441\u043b\u0430\u0431\u043e\u0432\u0430\u0442 \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447, \u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441 Haskell. \u0422\u043e, \u0447\u0442\u043e \u0432 Haskell \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u0447\u043a\u0443, \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0438\u043b\u0438\u0439 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0432 Scala. \u0422\u0430\u043a\u0436\u0435 \u0441\u0442\u0438\u043b\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439 \u0437\u0430\u0441\u043e\u0440\u044f\u0435\u0442 \u0441\u0442\u0435\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0447\u0442\u043e \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442 \u043e\u0442\u043b\u0430\u0434\u043a\u0443 \u043a\u043e\u0434\u0430. \u041d\u043e, \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 CPS \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u043c\u0430\u0441\u043a\u0438\u0440\u0443\u044e\u0442 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0442 \u0441\u0442\u0435\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043b\u0438\u0442\u0435\u0440\u0430\u0442\u0443\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>wiki-\u0441\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u0441\u0442\u0438\u043b\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439: <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9F%D1%80%D0%BE%D0%B4%D0%BE%D0%BB%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 (\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u043a\u0430)<\/a>,<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/en.wikibooks.org\/wiki\/Haskell\/Continuation_passing_style\" rel=\"noopener noreferrer nofollow\">Haskell\/Continuation passing style<\/a>;<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0430 \u0425\u0430\u0431\u0440\u0435 \u043f\u0440\u043e CPS (\u0441\u043c\u0435\u0441\u044c \u0440\u0443\u0441\u0441\u043a\u043e\u0433\u043e \u0441 \u0445\u0430\u0441\u043a\u0435\u043b\u0435\u043c): <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/149174\/\" rel=\"noopener noreferrer nofollow\">\u041c\u043e\u043d\u0430\u0434\u0430 ContT \u0432 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430\u0445<\/a> \u2013 \u0442\u0443\u0442 \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043c\u044b\u0441\u043b <code>calcCC<\/code>,<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/127040\/\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0432 Haskell<\/a> \u2013 \u0442\u0443\u0442, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>getCC<\/code>;<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0435\u0449\u0451 \u043f\u0440\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f: <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/ro-che.info\/articles\/2019-06-07-why-use-contt\" rel=\"noopener noreferrer nofollow\">Why would you use ContT?<\/a> \u0441\u0442\u0430\u0442\u044c\u044f \u0420\u043e\u043c\u0430\u043d\u0430 \u0427\u0435\u043f\u043b\u044f\u043a\u0430,<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/45334985\/when-to-use-cps-vs-codensity-vs-reflection-without-remorse-in-haskell\" rel=\"noopener noreferrer nofollow\">when to use CPS vs codensity vs reflection without remorse in Haskell<\/a> \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0430 Stackoverflow;<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b: <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/www.eff-lang.org\/handlers-tutorial.pdf\" rel=\"noopener noreferrer nofollow\">An Introduction to Algebraic Effects and Handlers<\/a> pdf-\u0441\u0442\u0430\u0442\u044c\u044f \u041c\u0430\u0442\u0438\u0438 \u041f\u0440\u0435\u0442\u043d\u0430\u0440\u0430,<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/arxiv.org\/pdf\/1905.06544.pdf\" rel=\"noopener noreferrer nofollow\">Effects Without Monads: Non-determinism Back to the Meta Language<\/a> pdf-\u0441\u0442\u0430\u0442\u044c\u044f \u041e\u043b\u0435\u0433\u0430 \u041a\u0438\u0441\u0435\u043b\u0451\u0432\u0430,<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/470718\/\" rel=\"noopener noreferrer nofollow\">\u00ab\u0410\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b\u00bb \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438\u043c \u044f\u0437\u044b\u043a\u043e\u043c<\/a> \u2013 \u0445\u0430\u0431\u0440-\u043f\u0440\u0435\u0432\u043e\u0434 <a href=\"https:\/\/overreacted.io\/algebraic-effects-for-the-rest-of-us\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0438<\/a> \u0414\u0430\u043d\u0430 \u0410\u0431\u0440\u0430\u043c\u043e\u0432\u0430,<\/p>\n<\/li>\n<li>\n<p>\u0445\u043e\u0440\u043e\u0448\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u0443\u044e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0438\u043c\u0435\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Kyo: <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/speakerdeck.com\/fwbrasil\/kyo-functional-scala-2023\" rel=\"noopener noreferrer nofollow\">Kyo &#8212; Functional Scala\u00a02023<\/a> (\u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044f),<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.scalamatters.io\/post\/writing-modular-applications-using-the-kyo-library\" rel=\"noopener noreferrer nofollow\">Writing Modular Applications Using The Kyo Library<\/a> \u2013 \u0441\u0442\u0430\u0442\u044c\u044f \u0425\u043e\u0440\u0445\u0435 \u0412\u0430\u0441\u043a\u0435\u0441\u0430;<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c (direct style): <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=0Fm0y4K4YO8\" rel=\"noopener noreferrer nofollow\">Martin Odersky DIRECT STYLE SCALA<\/a> \u2013 \u0432\u0438\u0434\u0435\u043e-\u0434\u043e\u043a\u043b\u0430\u0434 \u043e\u0442 \u0430\u0432\u0442\u043e\u0440\u0430 \u044f\u0437\u044b\u043a\u0430,<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/medium.com\/scala-3\/scala-3-what-is-direct-style-d9c1bcb1f810\" rel=\"noopener noreferrer nofollow\">Scala 3: What Is \u201cDirect Style\u201d?<\/a> \u2013 \u0441\u0442\u0430\u0442\u044c\u044f \u0414\u0438\u043d\u0430 \u0412\u0430\u043c\u043f\u043b\u0435\u0440\u0430 \u043d\u0430 Medium.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"tagless_final\" id=\"tagless_final\"><\/a><\/p>\n<h4>Tagless Final<\/h4>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0449\u0451 \u0440\u0430\u0437 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0430 <code>UsersRepo<\/code>, \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u043f\u0440\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432:<\/p>\n<pre><code class=\"scala\">enum UsersRepo[A]:   case Get(id: UserId)                 extends UsersRepo[Option[UserInfo]]   case Put(id: UserId, user: UserInfo) extends UsersRepo[UserSaved]   case ListAll                         extends UsersRepo[List[(UserId, UserInfo)]]<\/code><\/pre>\n<p>\u0420\u0430\u043d\u0435\u0435 \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0438\u043f (GADT) <em>\u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442<\/em> \u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435\u044f\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u0432 \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435. \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u201c<em>\u0431\u0435\u0437 \u043f\u043e\u0442\u0435\u0440\u044c<\/em>\u201c, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0442\u0438\u043f\u0430 <code>UsersRepo[A]<\/code> \u043c\u043e\u0436\u043d\u043e <em>\u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438<\/em>-\u043f\u043e\u0434\u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438, \u0438 \u0443\u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u043c \u0438 <em>\u0438\u0437 \u043a\u0430\u043a\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/em> \u044d\u0442\u043e\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u043e\u0437\u0434\u0430\u043d. \u041f\u043e \u0441\u0443\u0442\u0438, \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u0434\u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432.<\/p>\n<p>\u042d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>UsersRepo[A]<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440. \u041d\u043e \u0432\u043e\u0442 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u0438\u043d\u043e\u0439 <em>\u043d\u0435\u0438\u0437\u043e\u043c\u043e\u0440\u0444\u043d\u044b\u0439<\/em> \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0439 \u0442\u0438\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0440\u0430\u0436\u0430\u043b \u0431\u044b \u0441\u0443\u0442\u044c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0430, \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043a <code>UsersRepo<\/code> \u0443\u0436\u0435 \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442. \u0422\u043e \u0435\u0441\u0442\u044c, \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438 \u0442\u0430\u043a\u0438\u0435 \u0442\u0438\u043f\u044b \u043c\u043e\u0436\u043d\u043e \u043b\u0438\u0448\u044c <em>\u0443\u0441\u043b\u043e\u0436\u043d\u0438\u0442\u044c<\/em>, \u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0449\u0435 \u0443\u0436\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u0412 \u044d\u0442\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 GADT \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 <em><u>\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c\u0438<\/u><\/em> <em>\u0430\u043b\u0433\u0435\u0431\u0440\u0430\u043c\u0438<\/em> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430.<\/p>\n<p>\u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 <code>UsersRepo<\/code>, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443, \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f <em><u>\u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u043c<\/u><\/em> \u0448\u0430\u0433\u043e\u043c. \u0420\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 \u0434\u0432\u0430 \u0448\u0430\u0433\u0430 \u2013 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u0435\u0451 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u044f \u2013 \u0432\u0435\u0434\u0451\u0442 \u043a \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0439 \u043f\u043e\u0442\u0435\u0440\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0447\u0442\u043e, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043d\u0435 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u0415\u0441\u043b\u0438 \u201c\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0443\u044e \u0430\u043b\u0433\u0435\u0431\u0440\u0443\u201d <code>UsersRepo<\/code> \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0432 \u201c\u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439\u201d \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <code>IO<\/code>, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0439:<\/p>\n<pre><code class=\"scala\">trait UserRepoIO:   val getUser:   UserId             => IO[Option[UserInfo]]   val putUser:   UserId => UserInfo => IO[UserSaved]   val listUsers:                       IO[List[(UserId, UserInfo)]]<\/code><\/pre>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u041e\u041e\u041f-\u0448\u043d\u044b\u0439 \u0442\u0440\u0435\u0439\u0442 <code>UserRepoIO<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u0435 <code>UsersRepo<\/code>. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0435\u0433\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0432 \u043e\u0434\u0438\u043d \u0448\u0430\u0433. \u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u043c \u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u0430\u044f \u0436\u0451\u0441\u0442\u043a\u043e\u0441\u0442\u044c \u2013 \u0445\u043e\u0442\u044f \u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u044d\u0442\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u043d\u043e \u0432 \u0438\u0445 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0435 \u0443\u0436\u0435 \u0432\u0448\u0438\u0442 \u0442\u0438\u043f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u0447\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u044e.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443 \u0441 \u0435\u0451 \u201c\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e\u201d \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u201c\u0441\u0432\u043e\u0431\u043e\u0434\u0443 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0438\u201d, \u043f\u0440\u0438\u0441\u0443\u0449\u0443\u044e \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c <code>IO<\/code> \u0432 <code>UserRepoIO<\/code> \u043d\u0430 \u043d\u0435\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <code>F<\/code>:<\/p>\n<pre><code class=\"scala\">trait UserRepoF[F[_]]: \/\/ \u043d\u0435\u043a\u0438\u0439 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 F   val getUser:   UserId             => F[Option[UserInfo]]   val putUser:   UserId => UserInfo => F[UserSaved]   val listUsers:                       F[List[(UserId, UserInfo)]]<\/code><\/pre>\n<p>\u0412\u043d\u0435\u0437\u0430\u043f\u043d\u043e, \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u0438\u0441\u043a\u043e\u043c\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435! \u0412 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u043f\u043e\u043c\u043e\u0433\u0430\u043b\u0430 \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, <em>\u0442\u0435\u0445\u043d\u0438\u043a\u0430 Tagless Final \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430<\/em>, \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u044d\u0444\u0444\u0435\u043a\u0442\u0430. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0442\u0440\u0435\u0439\u0442\u0430 (\u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0438 \u0430\u043b\u0433\u0435\u0431\u0440\u044b <code>UserRepoF<\/code>):<\/p>\n<pre><code class=\"scala\">type Log[X] = String \/\/ \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 val log = new UserRepoF[Log]:   val getUser   = id         => s\"\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c $id\"   val putUser   = id => user => s\"\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f $user \u043f\u043e\u0434 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c $id\"   val listUsers =                \"\u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\"<\/code><\/pre>\n<p>\u0412 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430; \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>Log<\/code>, \u044d\u0442\u043e <code>String<\/code>. \u0410 \u0432\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0443\u044e \u0430\u043b\u0433\u0435\u0431\u0440\u0443:<\/p>\n<pre><code class=\"scala\">import UsersRepo.* val usersRepoAlg = new UserRepoF[UsersRepo]:   val getUser   = Get.apply   val putUser   = Put.apply.curried   val listUsers = ListAll<\/code><\/pre>\n<p>\u041e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0440\u0435\u0439\u0442\u044b \u0432\u0440\u043e\u0434\u0435 <code>UserRepoF<\/code>, \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u043c \u0436\u0435 \u043a\u043e\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043d\u044b\u043c \u0442\u0438\u043f\u043e\u043c-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c <code>F[_]<\/code>, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u043b\u0435\u0433\u043a\u043e \u0443\u0437\u043d\u0430\u0432\u0430\u0435\u043c\u0443\u044e \u043e\u0441\u043d\u043e\u0432\u0443 \u0442\u0435\u0445\u043d\u0438\u043a\u0438 Scala-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0443\u044e \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <strong>Tagless Final<\/strong>. \u0421\u043b\u043e\u0432\u043e \u201cfinal\u201d \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e <em>\u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439<\/em> \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438. \u201cTagless\u201d \u0436\u0435 \u043e\u0442\u0441\u044b\u043b\u0430\u0435\u0442 <s>\u043a \u0434\u0440\u0435\u0432\u043d\u0435\u043c\u0443 \u0437\u043b\u0443<\/s> \u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0430\u043c, \u043a\u043e\u0433\u0434\u0430 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0431\u043b\u044e\u0441\u0442\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u0441\u0432\u0435\u0440\u044f\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u201c\u0442\u0435\u0433\u0438\u201d \u2013 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0446\u0435\u043b\u0435\u0432\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438. \u041f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u043b\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 \u044d\u0442\u0430\u043f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u201c\u0431\u0435\u0441\u0442\u0435\u0433\u043e\u0432\u043e\u0439\u201d (tagless) \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441 \u043e\u0441\u043d\u043e\u0432\u043e\u0439 Tagless Final \u0431\u043e\u043b\u0435\u0435 \u0438\u043b\u0438 \u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043b\u0438\u0441\u044c, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f, \u043a\u0430\u043a \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0411\u0443\u0434\u0435\u043c \u0442\u0440\u0430\u043a\u0442\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u0439\u0442 <code>UserRepoF<\/code> \u043a\u0430\u043a <em>\u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432<\/em>. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>UserRepoF[SomeF]<\/code> \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e <code>SomeF<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u0421\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0435 \u201c\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439\u201d \u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u043c \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u043c (\u043a\u043e\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043d\u044b\u043c) \u0442\u0438\u043f\u0430\u043c \u0432\u0438\u0434\u0430 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\star\\Rightarrow\\star\" alt=\"\\star\\Rightarrow\\star\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/10a\/aee\/a71\/10aaeea71ac576c4a440e97549934f26.svg\" width=\"49\" height=\"14\"\/>, \u043a\u043e\u0433\u0434\u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u044b \u0442\u0438\u043f\u043e\u0432. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 Tagless Final \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0442\u0438\u043f\u043e\u0432 \u043a\u0430\u043a \u0432\u0441\u0435\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0430\u043b\u0433\u0435\u0431\u0440<\/p>\n<pre><code class=\"scala\">trait SearchServcieF[F[_]]:   def searchBest   (request: String): F[Data]   def searchSeveral(request: String): F[List[(Relevance, Data)]]  trait NotificationServiceF[F[_]]:   def sendNotification(notification: Notification): F[NotificationResult]<\/code><\/pre>\n<p>\u0442\u0430\u043a \u0438 \u201c\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445\u201d, \u0432\u0440\u043e\u0434\u0435 <a href=\"https:\/\/typelevel.org\/cats\/typeclasses\/monad.html\" rel=\"noopener noreferrer nofollow\">Monad<\/a> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Cats, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b <code>map<\/code> \u0438 <code>flatMap<\/code>:<\/p>\n<pre><code class=\"scala\">import cats.Monad import cats.syntax.all.*  def programTF[F[_]: UserRepoF: SearchServcieF: NotificationServiceF: Monad]: F[List[(Relevance, Data)]] =   val userRepo = summon[UserRepoF[F]]   import userRepo.*    val searchService = summon[SearchServcieF[F]]   import searchService.*    val notificationService = summon[NotificationServiceF[F]]   import notificationService.*    \/\/ \u0434\u0430\u043b\u0435\u0435 \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 \u043a\u043e\u0434   searchBest(\"best user\")           productL   sendNotification(\"user captured\") flatMap   putUser(42)                       productR   getUser(42)                       map   {_.fold(\"\")(_.reverse)}           flatMap   putUser(24)                       productR   listUsers<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u201c\u043c\u0443\u0441\u043e\u0440\u043d\u044b\u0445\u201d \u043f\u0440\u0438\u0437\u044b\u0432\u043e\u0432 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432 \u0432 \u0442\u0435\u043b\u0435 <code>programTF<\/code> \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 DSL \u0434\u043b\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0430\u043b\u0433\u0435\u0431\u0440:<\/p>\n<pre><code class=\"scala\">object UserRepoF:   def getUser  [F[_]: UserRepoF] = summon[UserRepoF[F]].getUser   def putUser  [F[_]: UserRepoF] = summon[UserRepoF[F]].putUser   def listUsers[F[_]: UserRepoF] = summon[UserRepoF[F]].listUsers  object SearchServcieF:   def searchBest   [F[_]: SearchServcieF] = summon[SearchServcieF[F]].searchBest   def searchSeveral[F[_]: SearchServcieF] = summon[SearchServcieF[F]].searchSeveral  object NotificationServiceF:   def sendNotification[F[_]: NotificationServiceF] = summon[NotificationServiceF[F]].sendNotification<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c <em>\u0432 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a\u043e\u0435 \u0436\u0435 \u0442\u0435\u043b\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b<\/em>, \u043a\u0430\u043a \u0438 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0434\u043b\u044f \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u043d\u043e \u0443\u0436\u0435 \u0432 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435:<\/p>\n<pre><code class=\"scala\">import UserRepoF.*, SearchServcieF.*, NotificationServiceF.*  def programTF[F[_]: UserRepoF: SearchServcieF: NotificationServiceF: Monad] =   searchBest(\"best user\")           productL   sendNotification(\"user captured\") flatMap   putUser(42)                       productR   getUser(42)                       map   {_.fold(\"\")(_.reverse)}           flatMap   putUser(24)                       productR   listUsers<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043d\u0435\u044f\u0432\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0430\u043b\u0433\u0435\u0431\u0440, \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c (\u0441\u0430\u043c\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u044b):<\/p>\n<pre><code class=\"scala\">given UserRepoF[IO] with   override val getUser   = ???   override val putUser   = ???   override val listUsers = ???  given SearchServcieF[IO] with   override val searchBest    = ???   override val searchSeveral = ???  given NotificationServiceF[IO] with   override val sendNotification = ???<\/code><\/pre>\n<p>\u0410\u043b\u0433\u0435\u0431\u0440\u0430 <code>Monad[IO]<\/code> \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435-\u043a\u043e\u043c\u043f\u0430\u043d\u044c\u043e\u043d\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>IO<\/code> \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443:<\/p>\n<pre><code class=\"scala\">programTF[IO] \/\/ : IO[List[(UserId, UserInfo)]]<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>programTF<\/code>, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043c\u0435\u0442\u043e\u0434\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u044b, \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0439 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0441 Tagless Final \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438 \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0439\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0422\u0435\u0445\u043d\u0438\u043a\u0430 Tagless Final \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u043e\u0447\u0435\u0442\u0430\u0435\u0442\u0441\u044f \u0441 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 Cats, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043a\u0430\u043a \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u201c\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435\u201d \u043a\u043b\u0430\u0441\u0441\u044b \u0442\u0438\u043f\u043e\u0432, \u0442\u0430\u043a \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u0432\u0440\u043e\u0434\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a, \u0438\u043b\u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0449\u0438\u043d\u044b. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/typelevel.org\/cats-tagless\/\" rel=\"noopener noreferrer nofollow\">Cats-tagless<\/a> \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0431\u043e\u0440 \u043c\u0430\u043a\u0440\u043e-\u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439 \u0434\u043b\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0430\u043b\u0433\u0435\u0431\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043e\u0431\u044a\u0451\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442 \u0434\u0440\u0443\u0433\u0438\u0435 \u0432\u043a\u0443\u0441\u043d\u044b\u0435 \u043f\u043b\u044e\u0448\u043a\u0438. \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b <code>ZIO<\/code> \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c\u0438 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u043c\u0438, \u043d\u043e \u044d\u0442\u0430 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u0442\u0430\u0440\u0430\u0435\u0442\u0441\u044f \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 Tagless Final, \u0433\u043e\u0432\u043e\u0440\u044f, \u0447\u0442\u043e \u0434\u043b\u044f ZIO-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044d\u0442\u043e \u0432\u0441\u0451 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<p>Tagless Final \u0434\u0430\u0451\u0442 \u0445\u043e\u0440\u043e\u0448\u0443\u044e \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432 \u0432\u044b\u0441\u043e\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430. \u0411\u0443\u0434\u0443\u0447\u0438 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0442\u0438\u043f\u0430\u0445 \u0432\u0438\u0434\u0430 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\star\\Rightarrow\\star\" alt=\"\\star\\Rightarrow\\star\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/754\/a90\/c13\/754a90c13495805eaf3117d0c9e7e502.svg\" width=\"49\" height=\"14\"\/>, \u043e\u043d\u0430 \u043e\u043f\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0438\u043f\u0430\u043c\u0438-\u0430\u043b\u0433\u0435\u0431\u0440\u0430\u043c\u0438 \u0432\u0438\u0434\u0430 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"(\\star\\Rightarrow\\star)\\Rightarrow\\star\" alt=\"(\\star\\Rightarrow\\star)\\Rightarrow\\star\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/905\/803\/1fc\/9058031fc4b595395c5ddd9b42131d89.svg\" width=\"104\" height=\"22\"\/>. \u0410 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u041b\u0443\u043a\u0438 \u042f\u043a\u0443\u0431\u043e\u0432\u0438\u0447\u0430 <a href=\"https:\/\/typelevel.org\/blog\/2017\/12\/27\/optimizing-final-tagless.html\" rel=\"noopener noreferrer nofollow\">Optimizing Tagless Final \u2013 saying farewell to Free<\/a> \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0445 \u2013 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0438\u043c\u0435\u044e\u0442 \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0432\u0438\u0434 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"((\\star\\Rightarrow\\star)\\Rightarrow\\star)\\Rightarrow\\star\" alt=\"((\\star\\Rightarrow\\star)\\Rightarrow\\star)\\Rightarrow\\star\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e9d\/1f1\/693\/e9d1f1693318c799a336fbe7095dde71.svg\" width=\"159\" height=\"22\"\/>.<\/p>\n<p>\u041a\u0430\u043a \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u0442\u0435\u0445\u043d\u0438\u043a\u0430 Tagless Final \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e-\u0440\u0430\u0437\u043d\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, \u0438\u043b\u0438 \u0436\u0435 \u043a\u043e\u0433\u0434\u0430 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b. \u041d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0432\u043e\u0435\u0439 \u201c\u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438\u201d Tagless Final <em>\u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442 \u043b\u0438\u0448\u043d\u0435\u0433\u043e \u0448\u0430\u0433\u0430<\/em> \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<p>\u0413\u043e\u0432\u043e\u0440\u044f \u0436\u0435 \u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0439 \u0442\u0435\u0445\u043d\u0438\u043a\u0438, \u043e\u0431\u044b\u0447\u043d\u043e \u043e\u0442\u0441\u044b\u043b\u0430\u044e\u0442 \u043a \u0441\u0442\u0430\u0442\u044c\u0435 \u201c<a href=\"https:\/\/degoes.net\/articles\/tagless-horror\" rel=\"noopener noreferrer nofollow\">The False Hope of Managing Effects With Tagless-Final in Scala<\/a>\u201d \u0430\u0432\u0442\u043e\u0440\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 ZIO \u0414\u0436\u043e\u043d\u0430 \u0434\u0435 \u0413\u0443\u0441\u0430. \u0414\u0430, \u0442\u0430\u043c \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0441\u0442\u0440\u0435\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442, \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0441 \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 Cats, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0435\u0437\u043e\u043d\u043d\u044b\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0434\u0430\u0436\u0435 \u0434\u043b\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0445 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u044b \u201c\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\u201d, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0430\u043b\u0433\u0435\u0431\u0440 \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 <code>F[_]: Monad<\/code> \u2013 \u043a\u043e\u0434 \u0443\u0436\u0435 \u0442\u0435\u0440\u044f\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u043e\u043b\u044e \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0422\u043e \u0436\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0438 \u043a \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0434\u0440\u0443\u0433\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u0430\u043c \u0442\u0438\u043f\u043e\u0432, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u043c \u0437\u0430 \u201c\u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435\u201c \u044d\u0444\u0444\u0435\u043a\u0442\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>Async[F[_]]<\/code>). \u041d\u043e \u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0436\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u201c\u0441\u0432\u043e\u0431\u043e\u0434\u044b \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0438\u201d \u043d\u0430\u0432\u0440\u044f\u0434 \u043b\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u043d\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u2013 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u043b\u0433\u0435\u0431\u0440\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f <em>\u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e<\/em> \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 (\u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e, \u044d\u0442\u043e <code>IO<\/code> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Cats).<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043b\u0438\u0442\u0435\u0440\u0430\u0442\u0443\u0440\u0430:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/blog.rockthejvm.com\/tagless-final\/\" rel=\"noopener noreferrer nofollow\">Tagless Final in Scala<\/a> \u2013 \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043e\u0431\u0437\u043e\u0440 \u043e\u0442 \u0414\u0430\u043d\u0438\u044d\u043b\u044f \u0427\u043e\u043a\u044b\u0440\u043b\u0430\u043d\u0430 (Rock the JVM).<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/nrinaudo.github.io\/articles\/tagless_final.html\" rel=\"noopener noreferrer nofollow\">A &#171;quick&#187; introduction to Tagless Final<\/a> \u2013 \u0435\u0449\u0451 \u043e\u0434\u043d\u043e \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u201c\u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u201d \u041d\u0438\u043a\u043e\u043b\u044f \u0420\u0438\u043d\u0430\u0443\u0434\u043e.<\/p>\n<\/li>\n<li>\n<p>\u0425\u0430\u0431\u0440-\u0441\u0442\u0430\u0442\u044c\u044f <a href=\"https:\/\/habr.com\/ru\/articles\/325874\/\" rel=\"noopener noreferrer nofollow\">\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u043a \u041d\u0435\u0440\u0430\u0437\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u043c \u041a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u0418\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430\u043c \u0441 Dotty<\/a>.<\/p>\n<\/li>\n<li>\n<p>\u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f PDF-\u0441\u0442\u0430\u0442\u044c\u044f <a href=\"https:\/\/okmij.org\/ftp\/tagless-final\/JFP.pdf\" rel=\"noopener noreferrer nofollow\">Finally Tagless, Partially Evaluated<\/a>.<\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"arrows\" id=\"arrows\"><\/a><\/p>\n<h4>\u041a\u043b\u0435\u0439\u0441\u043b\u0438 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0442\u0440\u0435\u0301\u043b\u043a\u0438<\/h4>\n<p>\u0418\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u201c\u0447\u0438\u0441\u0442\u043e\u201d \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u0439 \u0441\u0442\u0430\u0440\u0438\u043d\u043d\u043e\u0439 \u043c\u0430\u043d\u0435\u0440\u0435, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0442\u0435\u043a\u0430. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0448\u0430\u0433\u0438, \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044f\u0449\u0438\u0435 \u043e\u0434\u043d\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0442\u0435\u043a\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435. \u042d\u0442\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u0438\u0437 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/40b\/daf\/29e\/40bdaf29e2160399f66236912d2923cb.png\" alt=\"\u0421\u0442\u0435\u043a \u043d\u0430\u0440\u0430\u0441\u0442\u0430\u0435\u0442 \u0437\u0430 \u0441\u0447\u0451\u0442 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043f\u0440\u0438 \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u0442\u0430\u0440\u044b\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u043c\u0438.\" title=\"\u0421\u0442\u0435\u043a \u043d\u0430\u0440\u0430\u0441\u0442\u0430\u0435\u0442 \u0437\u0430 \u0441\u0447\u0451\u0442 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043f\u0440\u0438 \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u0442\u0430\u0440\u044b\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u043c\u0438.\" width=\"932\" height=\"640\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/40b\/daf\/29e\/40bdaf29e2160399f66236912d2923cb.png\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0435\u043a \u043d\u0430\u0440\u0430\u0441\u0442\u0430\u0435\u0442 \u0437\u0430 \u0441\u0447\u0451\u0442 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043f\u0440\u0438 \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u0442\u0430\u0440\u044b\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u043c\u0438.<\/figcaption><\/div>\n<\/figure>\n<p>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0440\u0435\u0434\u043a\u043e \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0447\u0440\u0435\u0432\u0430\u0442\u043e \u0431\u0443\u043a\u0435\u0442\u043e\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c:<\/p>\n<ul>\n<li>\n<p>\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u0430\u0441\u0442\u0451\u0442 \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u0448\u0430\u0433\u043e\u043c, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u201c\u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0430\u044e\u0442\u201d, \u0437\u0430\u0441\u043e\u0440\u044f\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442: <\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435, \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e \u043f\u0435\u0440\u0435\u043f\u0443\u0442\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0448\u0430\u0433\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f <em>\u0434\u043e<\/em> \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0445 \u043d\u0430\u0434\u043e\u0431\u043d\u043e\u0441\u0442\u0438), \u0438\u043b\u0438 \u0436\u0435<\/p>\n<\/li>\n<li>\n<p>\u0432\u043c\u0435\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u201c\u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0443\u044e\u201c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0442\u043e\u0433\u043e \u0436\u0435 \u0442\u0438\u043f\u0430 \u0438 \u0442.\u043f.;<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u044b \u0443\u043c\u043d\u0435\u044e\u0442, \u043d\u043e \u043c\u044b \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043e\u0442\u043d\u043e\u0441\u0438\u043c\u0441\u044f \u043a \u043d\u0438\u043c \u043a\u0430\u043a \u043a \u201c\u0434\u0443\u0440\u043e\u0447\u043a\u0430\u043c\u201d, <em>\u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u043e<\/em> \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u044f, \u043a\u0443\u0434\u0430 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u043a\u0430\u043a \u043f\u043e\u0442\u043e\u043c \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c; <\/p>\n<ul>\n<li>\n<p>\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435!) \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u0432\u0440\u043e\u0434\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445,<\/p>\n<\/li>\n<li>\n<p>\u0441\u0442\u0440\u0430\u0434\u0430\u0435\u0442 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430, \u0447\u0442\u043e, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043f\u0440\u043e\u0441\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044e \u043e\u0448\u0438\u0431\u043e\u043a \u043d\u0430 \u044d\u0442\u0430\u043f \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u0421 \u0442\u0430\u043a\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0441\u0430\u043c\u043e \u0441\u0442\u0440\u0435\u043c\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043a \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u043c\u0443 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u0441\u0442\u0438\u043b\u044e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a <em>\u043f\u043e\u0438\u0441\u043a \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0445 \u0433\u0440\u0430\u0431\u043b\u0435\u0439 \u0434\u043b\u044f \u043d\u0430\u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043c\u043e\u0437\u043e\u043b\u0438 \u043d\u0430 \u043b\u0431\u0443<\/em>.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u0441\u0442\u0438\u043b\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c <em>\u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/em> (flow syntax), \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0448\u0430\u0433\u0430\u043c\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439:<\/p>\n<pre><code class=\"scala\">def calc(b: Boolean) = b   .toString   .length   .+(37) \/\/ \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \"+\" - \u044d\u0442\u043e \u0441\u0430\u043c\u044b\u0439 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432 Scala  calc(false) \/\/ 42<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u0432\u044b\u0437\u043e\u0432\u0435 \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u0447\u043a\u0443 <code>.<\/code> \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0438\u043b\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f. \u041d\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"scala\">def boolToString(b: Boolean) = b.toString def stringToInt (s: String)  = s.length def add37       (i: Int)     = i + 37  import scala.util.chaining.scalaUtilChainingOps  def calc(b: Boolean) =   b            pipe   boolToString pipe   stringToInt  pipe   add37<\/code><\/pre>\n<p>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 <code>pipe<\/code> \u2013 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434-\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435, \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u0437 <code>scalaUtilChainingOps<\/code> \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 <a href=\"https:\/\/docs.scala-lang.org\/style\/method-invocation.html#arity-1-infix-notation\" rel=\"noopener noreferrer nofollow\">\u0432 \u0438\u043d\u0444\u0438\u043a\u0441\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u0435<\/a>. \u041e\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u043b\u0435\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0441\u043f\u0440\u0430\u0432\u0430 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0435). \u041a\u0441\u0442\u0430\u0442\u0438, \u043f\u043e\u0445\u043e\u0436\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0430\u0441\u044c \u0434\u043b\u044f <em>\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445<\/em> \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0433\u0434\u0435 \u0432\u043c\u0435\u0441\u0442\u043e <code>pipe<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 <code>flatMap<\/code>.<\/p>\n<p>\u0423\u0436\u0435 \u043b\u0443\u0447\u0448\u0435, \u043d\u043e \u043c\u044b \u0432\u0441\u0451 \u0435\u0449\u0451 \u043d\u0435 \u0438\u0437\u0431\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0442 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u041d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0448\u0430\u0433\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0432 <code>calc<\/code> \u0443 \u043d\u0430\u0441 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043e\u0431\u043b\u0430\u0437\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u201c\u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0443\u044e\u201d, \u043d\u043e \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0443\u044e, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>b<\/code>, \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u0443\u044e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043a\u0430\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442. \u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443? \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0435\u0441\u043b\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0441\u0451 \u0441\u0440\u0430\u0437\u0443 \u0432 <em>\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435<\/em>, \u043a\u043e\u0433\u0434\u0430 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 <em>\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438<\/em> \u043f\u0440\u043e\u0441\u0442\u044b\u0445:<\/p>\n<pre><code class=\"scala\">val calc = \/\/ : Boolean => Int - \u0442\u0438\u043f \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438   boolToString andThen   stringToInt  andThen   add37    calc(false) \/\/ 42<\/code><\/pre>\n<p>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 <code>andThen<\/code> \u0437\u0434\u0435\u0441\u044c \u2013 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Function1<\/code>. \u0418\u0442\u043e\u0433\u043e\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0435\u0441\u0442\u044c \u201c<em>boolToString, \u0437\u0430\u0442\u0435\u043c stringToInt, \u0437\u0430\u0442\u0435\u043c add37<\/em>\u201d. \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0438\u0434\u0435\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e, \u043d\u0438\u0447\u0435\u0433\u043e \u043b\u0438\u0448\u043d\u0435\u0433\u043e! \u041c\u044b \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0437\u0431\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u0435\u0442 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0435 <code>calc<\/code>, \u0442\u0443\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0447\u0435\u043c\u0443 \u043b\u043e\u043c\u0430\u0442\u044c\u0441\u044f! \u0422\u0430\u043a\u043e\u0439 \u0441\u0442\u0438\u043b\u044c \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u201c\u0431\u0435\u0441\u0442\u043e\u0447\u0435\u0447\u043d\u044b\u043c\u201d. \u041f\u043e\u0434 \u201c\u0442\u043e\u0447\u043a\u0430\u043c\u0438\u201d <s>\u0432 \u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439<\/s> \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u044e\u0442 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432 \u0441\u0442\u0435\u043a\u0435.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u0434\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>compose<\/code>, \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e <code>andThen<\/code>, \u043d\u043e \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438. \u0417\u0430\u043f\u0438\u0441\u044c <code>val calc = add37 compose stringToInt compose boolToString<\/code> \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0435\u0441\u0442\u044c \u043a\u0430\u043a \u201c<em>\u0444\u0443\u043d\u043a\u0446\u0438\u044f calc \u2013 \u044d\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f add37 \u043f\u043e\u0441\u043b\u0435 stringToInt, \u043f\u043e\u0441\u043b\u0435 boolToString<\/em>\u201d.<\/p>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0443\u0436\u043d\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0438\u0434\u0430 <code>A => F[B]<\/code>. \u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Cats \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b <code>andThenF<\/code> \u0438 <code>composeF<\/code>, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0434\u043b\u044f <code>F[_]<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043a\u043b\u0430\u0441\u0441 \u0442\u0438\u043f\u043e\u0432 <code>FlatMap[F[_]]<\/code> \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Cats \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0441\u0438\u043d\u043e\u043d\u0438\u043c\u044b \u0442\u0430\u043a\u0438\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u0435\u043b\u043e\u0447\u0435\u043a-\u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432: <code>>>><\/code>, <code>>=><\/code> \u0438 <code>&lt;&lt;&lt;<\/code>, <code>&lt;=&lt;<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"scala\">val stringToIntOpt: String => Option[Int] = _.toIntOption val devideOpt:         Int => Option[Int] =   i => if (42 % i == 0) Some(42 \/ i) else None  import cats.syntax.all.* val calc = devideOpt &lt;=&lt; stringToIntOpt \/\/                   \u2191\u2191\u2191 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 ? calc(\"7\") \/\/ Some(6)<\/code><\/pre>\n<p>C\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0438 \u201c\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445\u201d \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u041e\u0431\u0449\u0438\u0439 \u0432\u0438\u0434 \u044d\u0442\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0438\u043c:<\/p>\n<pre><code class=\"scala\">type ==>[-_, +_]<\/code><\/pre>\n<p>\u041f\u043e \u0441\u0443\u0442\u0438, <code>==><\/code> \u0438 \u0435\u0441\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u0430\u044f \u201c<em>\u0441\u0442\u0440\u0435\u043b\u043a\u0430<\/em>\u201d. \u041d\u043e \u0442\u0438\u043f\u044b, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0438 \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0441\u0432\u043e\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0442\u0438\u043f\u043e\u0432. \u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0442 \u0432\u043d\u0443\u0448\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432:<\/p>\n<pre><code class=\"scala\">type Identity   [==>[-_, +_]] = [A] => () => (A ==> A) type AndThen    [==>[-_, +_]] = [A, B, C] => (A ==> B, B ==> C) => (A ==> C) type Category   [==>[-_, +_]] = Identity[==>] &amp; AndThen[==>]  type Dimap      [==>[-_, +_]] = [A, B, C, D] => (C => A, B => D) => (A ==> B) => (C ==> D) type First      [==>[-_, +_]] = [A, B, C] => (A ==> B) => ((A, C) ==> (B, C)) \/\/ \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438, \u043c\u043e\u0436\u043d\u043e type Second     [==>[-_, +_]] = [A, B, C] => (A ==> B) => ((C, A) ==> (C, B)) \/\/ \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0438\u043c type Strong     [==>[-_, +_]] = Dimap[==>] &amp; First[==>] &amp; Second[==>]  type Arr        [==>[-_, +_]] = [A, B] => (A => B) => (A ==> B) type Arrow      [==>[-_, +_]] = Category[==>] &amp; Strong[==>] &amp; Arr[==>]  type Choose     [==>[-_, +_]] = [A, B, C, D] => ((A ==> C), (B ==> D)) => ((A Either B) ==> (C Either D)) type ArrowChoice[==>[-_, +_]] = Arrow[==>] &amp; Choose[==>]<\/code><\/pre>\n<p>\u0414\u043b\u044f \u044d\u0442\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0442\u0438\u043f\u043e\u0432 \u0432\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"scala\">def ident[==>[-_, +_] : Identity] = summon[Identity[==>]]()  extension[==>[-_, +_]: Dimap, A, B] (fab: A ==> B)   def dimap[C, D](ca: C => A, bd: B => D) = summon[Dimap[==>]](ca, bd)(fab)  extension[==>[-_, +_]: AndThen, A, B] (fab: A ==> B)   def andThen[C](fbc: B ==> C) = summon[AndThen[==>]](fab, fbc)   def >>>    [C](fbc: B ==> C) = fab andThen fbc     def compose[C](fca: C ==> A) = fca andThen fab   def &lt;&lt;&lt;    [C](fca: C ==> A) = fab compose fca  extension[==>[-_, +_]: First, A, B] (fab: A ==> B)   def first[C]  = summon[First [==>]][A, B, C](fab) extension[==>[-_, +_]: Second, A, B] (fab: A ==> B)   def second[C] = summon[Second[==>]][A, B, C](fab)  extension[A, B] (fab: A => B)   def arr[==>[-_, +_]: Arr] = summon[Arr[==>]](fab)  extension[==>[-_, +_]: Arrow, A, B] (fab: A ==> B)   def split[C, D](fcd: C ==> D) = fab.first andThen fcd.second   def ***  [C, D](fcd: C ==> D) = fab split fcd   def merge[C   ](fac: A ==> C) = ((a: A) => (a, a)).arr[==>] andThen (fab split fac)   def &amp;&amp;&amp;  [C   ](fac: A ==> C) = fab merge fac  extension[==>[-_, +_]: Choose, A, C] (fac: A ==> C)   def choose[B, D](fbd: B ==> D) = summon[Choose[==>]](fac, fbd)   def +++   [B, D](fbd: B ==> D) = fac choose fbd  extension[==>[-_, +_]: ArrowChoice, A, C] (fac: A ==> C)   def choice[B](fbd: B ==> C) = (fac +++ fbd).dimap(identity[A Either B], _.fold(identity, identity))   def ||| \u00a0 [B](fbd: B ==> C) = fac choice fbd<\/code><\/pre>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0443 \u0441\u0442\u0440\u0435\u043b\u043e\u043a \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c \u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432, \u043d\u043e \u0432 \u043a\u043e\u0434\u0435 \u0432\u044b\u0448\u0435 \u043c\u043d\u043e\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u0438\u043d\u043e\u043d\u0438\u043c\u0430\u043c\u0438 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432. \u0418\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0438 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b: <code>>>><\/code>, <code>&lt;&lt;&lt;<\/code>, <code>&amp;&amp;&amp;<\/code>, <code>***<\/code>, <code>+++<\/code>.<\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f <a href=\"https:\/\/typelevel.org\/cats\/typeclasses\/arrow.html\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0440\u0435\u043b\u043e\u043a \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Cats<\/a>. \u0422\u0430\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043d\u0435\u044f\u0432\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 <code>Arrow<\/code> \u0434\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432 <a href=\"https:\/\/typelevel.org\/cats\/datatypes\/kleisli.html\" rel=\"noopener noreferrer nofollow\">Kleisli<\/a> \u0438 <a href=\"https:\/\/typelevel.org\/cats\/api\/cats\/data\/Cokleisli.html\" rel=\"noopener noreferrer nofollow\">Cokleisli<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u043e\u043c\u043e\u0440\u0444\u043d\u044b \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c:<\/p>\n<pre><code class=\"scala\">type Function [ \u00a0 \u00a0 \u00a0 -A, +B] =   A  => \u00a0 B  \/\/ \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0430\u043b\u0430\u043c\u0431\u0443\u0440 ? type Kleisli  [F[+_], -A, +B] =   A  => F[B] \/\/ \u0441\u0438\u043d\u043e\u043d\u0438\u043c\u0438\u0447\u0435\u043d ReaderT type Cokleisli[F[+_], -A, +B] = F[A] =>   B  \/\/ \u0442\u043e\u0436\u0435 \u043c\u0435\u0441\u0442\u0430\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435\u043d, \u043d\u043e \u0442\u0443\u0442 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e \u043d\u0451\u043c<\/code><\/pre>\n<p>\u0411\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0435\u043b\u043a\u0443 \u0442\u0438\u043f\u0430 <code>Kleisli[IO, *, *]<\/code> \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u043e\u0432:<\/p>\n<pre><code class=\"scala\">import cats.effect.IO import cats.data.Kleisli import cats.syntax.all.*  type ==>[A, B] = Kleisli[IO, A, B]  val boolToString :  Boolean    ==> String = Kleisli{ b     => b.toString.pure} val getFirstChar :  String     ==> Char   = Kleisli{ s     => IO{s.head}} val stringToInt  :  String     ==> Int    = Kleisli{ s     => IO{s.length}} val replicateChar: (Char, Int) ==> String = Kleisli{(c, i) => (c.toString * i).pure}<\/code><\/pre>\n<p>\u0421\u0430\u043c\u0430 \u0436\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0431\u0435\u0441\u0442\u043e\u0447\u0435\u0447\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435:<\/p>\n<pre><code class=\"scala\">val program = boolToString >>> (getFirstChar &amp;&amp;&amp; stringToInt) >>> replicateChar \/\/  program : Boolean ==> String  import cats.effect.unsafe.implicits.global program(true).unsafeRunSync() \/\/ tttt<\/code><\/pre>\n<p>(\u041d\u0435\u0443\u0436\u0435\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u0432\u0441\u0451 \u0435\u0449\u0451 \u0445\u043e\u0447\u0435\u0442 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c \u0432 Scala?)<\/p>\n<p>\u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u043a\u043e\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043d\u044b \u043f\u043e \u0432\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0443, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043e\u043d\u0438 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c \u0438 \u0434\u043b\u044f \u043d\u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u041d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043e\u043d \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u0433\u0430\u0447\u0435. \u0420\u0430\u043d\u0435\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043a\u043b\u0430\u0441\u0441\u044b \u0442\u0438\u043f\u043e\u0432 <code>Applicative<\/code> \u0438 <code>Monad<\/code> \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043d\u0430, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0435 (\u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0435) \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432. \u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u0436\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u043e\u0431\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u043d\u0435 \u0438\u0441\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u0438\u0448\u044c <em>\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438<\/em> \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439, \u0432\u0438\u0434\u0430 <code>F[A] => G[B]<\/code>. \u041d\u0430 \u0441\u0430\u0439\u0442\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 Cats \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0439 \u0441\u0442\u0440\u0435\u043b\u043a\u0438 <a href=\"https:\/\/typelevel.org\/cats\/typeclasses\/arrow.html#fancyfunction\" rel=\"noopener noreferrer nofollow\">FancyFunction<\/a>. \u0418\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"scala\">type InverseFunction[-A, +B] = (B => A) => (A => B)<\/code><\/pre>\n<p>\u0425\u043e\u0442\u044c \u0438 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u201c\u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e\u201d, \u043d\u043e \u0434\u043b\u044f \u043d\u0435\u0451 \u0442\u043e\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u0442\u0440\u0435\u043b\u043e\u0447\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0421\u0442\u0440\u0435\u043b\u043a\u0438, \u0442\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u201c\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c\u0438\u201d. \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043d\u0430 \u0438\u0445 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 <a href=\"https:\/\/github.com\/AdrielC\/free-arrow#free-arrow\" rel=\"noopener noreferrer nofollow\">Free Arrow<\/a>. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0445 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0443\u0436\u0435 \u0434\u0432\u0443\u043c\u044f \u0442\u0438\u043f\u0430\u043c\u0438. \u0414\u0430\u043b\u0435\u0435 \u043e\u043d\u0438 \u201c\u043f\u043e\u0434\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f\u201d \u0434\u043e \u201c\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445 \u0441\u0442\u0440\u0435\u043b\u043e\u043a\u201d, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0443\u0436\u0435 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439. \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u201c\u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u201d \u2013 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u0437 \u043d\u0430\u0448\u0438\u0445 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0445 \u0441\u0442\u0440\u0435\u043b\u043e\u043a \u0432\u043e \u0447\u0442\u043e-\u0442\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u043c\u043e\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0442\u043e\u0442 \u0436\u0435 <code>Kleisli<\/code>. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439 \u043f\u0443\u0442\u044c, \u0447\u0442\u043e \u0438 \u0441\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438, \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0448\u0438\u0440\u043e\u043a\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0442\u0440\u0435\u043b\u043e\u043a \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<p>\u041d\u0435 \u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u043e\u0433\u0430\u0447\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u043d\u0430 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u0441\u0442\u0440\u0435\u043b\u043a\u0430\u0445 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u0438\u043c \u0434\u043b\u044f \u043f\u043e\u0432\u0441\u0435\u0434\u043d\u0435\u0432\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u0431\u044b\u0447\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e\u0442 \u0441\u0442\u043e\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 (\u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0441 <code>Kleisli<\/code> \u043d\u0430\u0434 \u043d\u0438\u043c\u0438), \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043c, \u0433\u0434\u0435 \u043e\u043d\u0438 \u043d\u0435 \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f, \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u0440\u0435\u043b\u043e\u043a. \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0432\u0441\u0451 \u044d\u0442\u043e \u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u0442 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0439 \u0444\u0430\u043a\u0442:<\/p>\n<blockquote>\n<p><em>\u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u043e\u0442\u0440\u0430\u0436\u0430\u044e\u0442 \u0441\u0430\u043c\u0443 \u0441\u0443\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/em>.<\/p>\n<\/blockquote>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043f\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0430\u043c:<\/p>\n<ul>\n<li>\n<p>\u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u0432 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 Scala-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445: <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/typelevel.org\/cats\/typeclasses\/arrow.html\" rel=\"noopener noreferrer nofollow\">Arrow<\/a> \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435 \u043e Cats \u043e\u0442 TypeLevel.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/eed3si9n.com\/herding-cats\/Arrow.html\" rel=\"noopener noreferrer nofollow\">Arrow<\/a> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Cats \u0441 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 <a href=\"https:\/\/eed3si9n.com\/herding-cats\/\" rel=\"noopener noreferrer nofollow\">herding cats<\/a> \u042e\u0434\u0436\u0438\u043d\u0430 \u0419\u043e\u043a\u043e\u0442\u044b.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/eed3si9n.com\/learning-scalaz\/Arrow.html#Arrow\" rel=\"noopener noreferrer nofollow\">Arrow<\/a> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Scalaz \u0441 \u0442\u043e\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430 <a href=\"https:\/\/eed3si9n.com\/learning-scalaz\/\" rel=\"noopener noreferrer nofollow\">learning Scalaz <\/a> \u0442\u043e\u0433\u043e \u0436\u0435 \u0430\u0432\u0442\u043e\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/zio.dev\/ecosystem\/community\/zio-arrow\/\" rel=\"noopener noreferrer nofollow\">ZIO Arrow<\/a> (\u0431\u0435\u0437 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u0432 Scala <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/wix\/articles\/304622\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u041a\u043b\u0435\u0439\u0441\u043b\u0438<\/a> \u2013 \u0445\u0430\u0431\u0440-\u0441\u0442\u0430\u0442\u044c\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>Kleisli<\/code> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Scalaz.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/blog.ssanj.net\/posts\/2017-06-07-composing-monadic-functions-with-kleisli-arrows.html\" rel=\"noopener noreferrer nofollow\">Composing Monadic Functions with Kleisli Arrows<\/a> \u0441\u0442\u0430\u0442\u044c\u044f \u0421\u0430\u043d\u0434\u0436\u0438\u0432\u0430 \u0421\u0430\u0445\u0430\u044f\u043c\u0430.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/workday.github.io\/assets\/scala-functional-programming-with-arrows\/\" rel=\"noopener noreferrer nofollow\">Functional Programming with Arrows<\/a> \u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u042e\u0440\u0438\u044f \u041f\u043e\u043b\u044e\u043b\u0438.<\/p>\n<\/li>\n<li>\n<p><em>Arrows, Monads and Kleisli<\/em> \u2013 \u0441\u0442\u0430\u0442\u044c\u044f \u0432 <a href=\"https:\/\/medium.com\/virtuslab\/arrows-monads-and-kleisli-part-i-6c2a35c27a6e\" rel=\"noopener noreferrer nofollow\">\u0434\u0432\u0443\u0445<\/a> <a href=\"https:\/\/medium.com\/virtuslab\/arrows-monads-and-kleisli-part-ii-12ffd4da8bc9\" rel=\"noopener noreferrer nofollow\">\u0447\u0430\u0441\u0442\u044f\u0445<\/a> \u043d\u0430 Medium \u043e\u0442 \u041c\u0430\u0440\u0446\u0438\u043d\u0430 \u0420\u0436\u0435\u0436\u043d\u0438\u0446\u043a\u043e\u0433\u043e.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0435\u043b\u043a\u0438 \u0432 Haskell: <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/en.m.wikibooks.org\/wiki\/Haskell\/Understanding_arrows\" rel=\"noopener noreferrer nofollow\">Understanding arrows<\/a> \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0441 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/3652054\/monads-vs-arrows\" rel=\"noopener noreferrer nofollow\">Monads vs. Arrows<\/a> \u2013 \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0430 Stackoverflow.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"subcategories_of_types\" id=\"subcategories_of_types\"><\/a><\/p>\n<h3>\u041f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0442\u0438\u043f\u043e\u0432 (\u0432\u043c\u0435\u0441\u0442\u043e \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f)<\/h3>\n<p>\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u0430\u043f\u044b, \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e <em>\u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0435<\/em> \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u044d\u0442\u0430\u043f-\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u044d\u0442\u0430\u043f\u0443-\u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435 \u0434\u043e \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0443, \u043e\u0431\u0440\u0430\u0437\u0443\u044f <em>\u043f\u0443\u0442\u044c<\/em> \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0433\u043e \u0433\u0440\u0430\u0444\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f23\/5a9\/192\/f235a9192854f50428548953600ba004.png\" width=\"1055\" height=\"98\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f23\/5a9\/192\/f235a9192854f50428548953600ba004.png\"\/><\/figure>\n<p>\u041d\u043e, \u043a\u0430\u043a \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, \u043d\u0435 \u0432\u0441\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u041f\u0440\u043e\u0441\u0442\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0442\u0438\u043f\u043e\u0432 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0432 \u0434\u0440\u0443\u0433\u0438\u0435. \u041d\u043e \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0438 \u0441\u0430\u043c\u0438 \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u043e\u0447\u0435\u043a-\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0434\u043b\u044f \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0438\u0441\u044c \u201c\u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0438\u044f\u201d \u043c\u0435\u0436\u0434\u0443 \u0432\u0441\u0435\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u043e\u0432, \u043a\u043e\u0433\u0434\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0437 \u0442\u043e\u0447\u043a\u0438-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0439\u0442\u0438 \u043a \u0442\u043e\u0447\u043a\u0435-\u0442\u0438\u043f\u0443, \u0438\u043b\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442.  \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0435\u0441\u0442\u044c \u0438 \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0441\u043e\u0432\u043e\u043a\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0442\u043e\u0447\u0435\u043a \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0442\u044c \u0438 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u044f\u0432\u043d\u043e, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438. \u0418 \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0443\u0436\u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043e\u0431\u0449\u0430\u044f \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f, \u0447\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u0438\u0445 \u0442\u0438\u043f\u044b.<\/p>\n<p>\u0422\u0430\u043a\u0430\u044f \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <strong>\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0435\u0439<\/strong>. \u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u0430\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043a\u0430\u043a \u0440\u0430\u0437 \u0441\u043e\u0432\u043e\u043a\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u043a\u0438\u0445 \u0442\u043e\u0447\u0435\u043a-<strong>\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/strong> \u0438 \u0441\u0442\u0440\u0435\u043b\u043e\u043a-<strong>\u043c\u043e\u0440\u0444\u0438\u0437\u043c\u043e\u0432<\/strong> \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0434\u043b\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0435\u0441\u0442\u044c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f: \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 <em>\u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438<\/em> \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u043e\u0432 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"g \\circ f\" alt=\"g \\circ f\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/daf\/383\/4f5\/daf3834f56453be515ba19b1348d06a0.svg\" width=\"38\" height=\"20\"\/>, \u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <em>\u0435\u0434\u0438\u043d\u0438\u0447\u043d\u043e\u0433\u043e \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430<\/em> <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"id\" alt=\"id\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/950\/682\/12d\/95068212dacf97bd21b364c3cea33e6a.svg\" width=\"17\" height=\"17\"\/>, \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0435\u0431\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1b3\/016\/909\/1b30169093bcba95952571af70cf2c7e.png\" alt=\"\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u2013 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u044b (\u043a\u0440\u0430\u0441\u043d\u044b\u0435), \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u044b \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 (\u0441\u0438\u043d\u0438\u0435 \u0438 \u0437\u0435\u043b\u0451\u043d\u044b\u0435). \u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0431\u044b\u043b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u043c\u043e\u0440\u0444\u0438\u0437\u043c (\u0437\u0435\u043b\u0451\u043d\u044b\u0435), \u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u043e\u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430 \u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f (\u0431\u0438\u0440\u044e\u0437\u043e\u0432\u044b\u0439).\" title=\"\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u2013 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u044b (\u043a\u0440\u0430\u0441\u043d\u044b\u0435), \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u044b \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 (\u0441\u0438\u043d\u0438\u0435 \u0438 \u0437\u0435\u043b\u0451\u043d\u044b\u0435). \u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0431\u044b\u043b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u043c\u043e\u0440\u0444\u0438\u0437\u043c (\u0437\u0435\u043b\u0451\u043d\u044b\u0435), \u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u043e\u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430 \u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f (\u0431\u0438\u0440\u044e\u0437\u043e\u0432\u044b\u0439).\" width=\"707\" height=\"704\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1b3\/016\/909\/1b30169093bcba95952571af70cf2c7e.png\"\/><\/p>\n<div><figcaption>\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u2013 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u044b (\u043a\u0440\u0430\u0441\u043d\u044b\u0435), \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u044b \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 (\u0441\u0438\u043d\u0438\u0435 \u0438 \u0437\u0435\u043b\u0451\u043d\u044b\u0435). \u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0431\u044b\u043b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0439 \u043c\u043e\u0440\u0444\u0438\u0437\u043c (\u0437\u0435\u043b\u0451\u043d\u044b\u0435), \u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u043e\u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430 \u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f (\u0431\u0438\u0440\u044e\u0437\u043e\u0432\u044b\u0439).<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a\u0430\u044f \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u0430\u044f, \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0430\u043c\u0438-\u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430\u043c\u0438 \u043d\u0430 \u0433\u0440\u0430\u0444\u0435, \u043d\u043e \u0446\u0435\u043b\u044b\u043c\u0438 <em>\u043f\u0443\u0442\u044f\u043c\u0438<\/em>, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c\u0438 \u0438\u0437 \u044d\u0442\u0438\u0445 \u0441\u0442\u0440\u0435\u043b\u043e\u043a \u2013 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0438\u0445 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043d\u0430\u0438\u043b\u0443\u0447\u0448\u0438\u0439.<\/p>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0441\u0432\u043e\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0442\u0438\u043f\u044b, \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0442\u0438\u043f\u043e\u0432, \u0432\u0438\u0434\u044b \u0442\u0438\u043f\u043e\u0432 \u0438 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u0435\u0449\u0451. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0442\u0438\u043f\u043e\u0432 <code>Either[A, B]<\/code> \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u043f\u0430\u0440\u0443 \u0442\u0438\u043f\u043e\u0432 \u0432 \u0442\u0438\u043f. \u041d\u043e <em>\u043f\u0430\u0440\u044b \u0442\u0438\u043f\u043e\u0432<\/em> \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 \u0442\u0438\u043f\u0430\u043c\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u2013 \u043e\u043d\u0438 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e! \u0410 <code>Either<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043c\u043e\u0440\u0444\u0438\u0437\u043c \u0438\u0437 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u043f\u0430\u0440 \u0442\u0438\u043f\u043e\u0432 \u0432 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e \u0442\u0438\u043f\u043e\u0432. \u041d\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0443\u0438\u0446\u0438\u044f, \u0447\u0442\u043e <em>\u0441\u043e\u0432\u043e\u043a\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u0441\u0430\u043c\u0430 \u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e<\/em>.<\/p>\n<p>\u0412 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u043d\u0430\u043c, \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u0432\u0430\u0436\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 <em>\u043f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438<\/em>. \u0412 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438, \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u0438\u043f\u044b, \u0430 \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430\u043c\u0438 \u2013 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>A => B<\/code>, <em>\u043a\u0430\u0436\u0434\u044b\u0439<\/em> \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0439 \u0442\u0438\u043f <code>F[_]<\/code> \u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0441\u0432\u043e\u044e <strong>\u043f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e \u0442\u0438\u043f\u043e\u0432<\/strong> \u0441 \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430\u043c\u0438-\u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 <code>F[A] => F[B]<\/code>. \u0418 \u044d\u0442\u043e \u0434\u0430\u0451\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u0443\u044e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u044e \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432.<\/p>\n<p>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f, \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0435 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435, \u0442\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u043e\u043f\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0442\u0435\u043e\u0440\u0438\u044e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439:<\/p>\n<ul>\n<li>\n<p>\u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430\u043c\u0438 \u0432\u0438\u0434\u0430 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\star\\rightarrow\\star\" alt=\"\\star\\rightarrow\\star\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c50\/d85\/08d\/c50d8508d1d66a421684dc666f5dd70d.svg\" width=\"49\" height=\"13\"\/> \u0432 <em>\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0442\u0438\u043f\u043e\u0432<\/em>;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0439 \u0442\u0438\u043f <code>F[_]<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 <em>\u043f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e \u0442\u0438\u043f\u043e\u0432<\/em> <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\mathcal{F}\" alt=\"\\mathcal{F}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/13a\/5bd\/f28\/13a5bdf282a48e66d728cab749b04bef.svg\" width=\"16\" height=\"17\"\/>;<\/p>\n<\/li>\n<li>\n<p>\u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0434\u043b\u044f \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u0432\u0438\u0434\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\star\\rightarrow\\star\\rightarrow\\star\" alt=\"\\star\\rightarrow\\star\\rightarrow\\star\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/258\/06b\/b4d\/25806bb4d0a9306d2909f1d9f6444a58.svg\" width=\"89\" height=\"13\"\/> \u0438 \u0434\u0440.);<\/p>\n<\/li>\n<li>\n<p>\u0432\u0441\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u043e\u0432 \u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e \u0441 \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430\u043c\u0438-\u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0438\u044f\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>\u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 <code>Lift[F[_]]<\/code> (\u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e <code>map<\/code>) \u043e\u043b\u0438\u0446\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 <em>\u044d\u043d\u0434\u043e\u0444\u0443\u043d\u043a\u0442\u043e\u0440<\/em> \u0438\u0437 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0435\u0439 \u0442\u0438\u043f\u043e\u0432 \u0432 \u0435\u0451 \u043f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e: <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"F: \\star\\rightarrow \\mathcal{F}\" alt=\"F: \\star\\rightarrow \\mathcal{F}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5fd\/8ab\/4a0\/5fd8ab4a082f7e8900184a5400fc446a.svg\" width=\"86\" height=\"17\"\/>;<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u043b\u043d\u0438\u0441\u0442\u0430\u044f \u0441\u0442\u0440\u0435\u043b\u043a\u0430 <code>~>[F[_], G[_]]<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 <s>\u0432\u043e\u043e\u0431\u0449\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, \u0444\u0443\u043d\u043a\u0442\u043e\u0440 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u043c\u0438 F \u0438 G, \u043d\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e<\/s> <em>\u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/em> <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"F\\leadsto G\" alt=\"F\\leadsto G\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bf8\/119\/ce6\/bf8119ce602bf113067b26e87fe49a0f.svg\" width=\"60\" height=\"17\"\/> \u043c\u0435\u0436\u0434\u0443 <em>\u044d\u043d\u0434\u043e\u0444\u0443\u043d\u043a\u0442\u043e\u0440\u0430\u043c\u0438<\/em> <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"F: \\star\\rightarrow \\mathcal{F}\" alt=\"F: \\star\\rightarrow \\mathcal{F}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c76\/c03\/52d\/c76c0352dd6b1fb2f537323f965e6bb0.svg\" width=\"86\" height=\"17\"\/> \u0438 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"G: \\star\\rightarrow \\mathcal{G}\" alt=\"G: \\star\\rightarrow \\mathcal{G}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/696\/b85\/731\/696b857310f17f91aa364e292e4c986e.svg\" width=\"82\" height=\"19\"\/>, \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0438\u0437 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0442\u0438\u043f\u043e\u0432 \u0432 \u043d\u0435\u0451 \u0436\u0435 (\u043f\u043e\u0442\u043e\u043c\u0443 \u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u201c<em>\u044d\u043d\u0434\u043e-<\/em>\u201d, &#171;<em>\u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439<\/em>&#171;);<\/p>\n<\/li>\n<li>\n<p>\u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043a\u043b\u0430\u0441\u0441 \u0442\u0438\u043f\u043e\u0432 <code>Flatten[F[_]]<\/code> \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 <code>Pure[F[_]]<\/code> \u0438 <code>Lift[F[_]]<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0442\u0430\u043a\u0443\u044e \u043f\u0430\u0440\u0443 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 (<code>pure<\/code> \u0438 <code>flatten<\/code>) \u0434\u043b\u044f \u044d\u043d\u0434\u043e\u0444\u0443\u043d\u043a\u0442\u043e\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043f\u043e\u043d\u044f\u0442\u0438\u044e <em>\u043c\u043e\u043d\u0430\u0434\u0430<\/em>;<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u043c\u0435\u0441\u0442\u0430\u043c\u0438 <code>F[G[A]] => G[F[A]]<\/code>, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u043a\u043e\u0433\u0434\u0430 \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u043a\u043e\u0440\u0442\u0435\u0436 (<code>Applicative<\/code>), \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u0444\u0443\u043d\u043a\u0442\u043e\u0440\u044b <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"F: \\star\\rightarrow \\mathcal{F}\" alt=\"F: \\star\\rightarrow \\mathcal{F}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cb8\/451\/f7f\/cb8451f7faa98538effc70936ca3e26e.svg\" width=\"86\" height=\"17\"\/> \u0438 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"G: \\star\\rightarrow \\mathcal{G}\" alt=\"G: \\star\\rightarrow \\mathcal{G}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3a9\/c17\/0de\/3a9c170ded2659b7e0445e1a3c784830.svg\" width=\"82\" height=\"19\"\/> <em>\u0441\u043e\u043f\u0440\u044f\u0436\u0435\u043d\u044b<\/em> \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c: <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"F\\vdash G\" alt=\"F\\vdash G\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/66d\/259\/6ba\/66d2596baf27f15249e31e51a3f78054.svg\" width=\"52\" height=\"17\"\/> \u0438\u043b\u0438 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"F\\dashv G\" alt=\"F\\dashv G\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fd1\/444\/483\/fd14444836ea8b5b615999b0795bb180.svg\" width=\"52\" height=\"17\"\/>;<\/p>\n<\/li>\n<li>\n<p>\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <code>Free[F[_]]<\/code> \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 <em>\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c (\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c) \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c<\/em> \u0432 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u043c\u043e\u043d\u0430\u0434 \u043d\u0430\u0434 \u0444\u0443\u043d\u043a\u0442\u043e\u0440\u043e\u043c <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"F\" alt=\"F\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8fb\/57a\/f82\/8fb57af82d43fa6da28f09c161a0f625.svg\" width=\"14\" height=\"17\"\/> \u2013 <em>\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c \u043c\u043e\u043d\u043e\u0438\u0434\u043e\u043c<\/em> \u0432 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u044d\u043d\u0434\u043e\u0444\u0443\u043d\u043a\u0442\u043e\u0440\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 \u043a\u043e\u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438 <code>Codensity[F[_]]<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 <em>\u043f\u0440\u0430\u0432\u043e\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u041a\u0430\u043d\u0430<\/em> \u0444\u0443\u043d\u043a\u0442\u043e\u0440\u0430 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"F: \\star\\rightarrow \\mathcal{F}\" alt=\"F: \\star\\rightarrow \\mathcal{F}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c27\/04a\/7e8\/c2704a7e8510966d41eb5c24f123d589.svg\" width=\"86\" height=\"17\"\/> <em>\u0432\u0434\u043e\u043b\u044c \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0435\u0431\u044f<\/em>: <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"Codensity(F)=Ran_F(F)\" alt=\"Codensity(F)=Ran_F(F)\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/164\/f89\/ecc\/164f89ecc4cec2fc55b164dfb9f3d3c3.svg\" width=\"220\" height=\"22\"\/>;<\/p>\n<\/li>\n<li>\n<p>\u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0436\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 <em>(\u0441\u0438\u043b\u044c\u043d\u044b\u0435) \u043f\u0440\u043e\u0444\u0443\u043d\u043a\u0442\u043e\u0440\u044b<\/em> \u2013 \u0444\u0443\u043d\u043a\u0442\u043e\u0440\u044b \u0432 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432 \u0438\u0437 \u0434\u0435\u043a\u0430\u0440\u0442\u043e\u0432\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\star^{op}\\times\\star \\rightarrow \\mathbf{Set}\" alt=\"\\star^{op}\\times\\star \\rightarrow \\mathbf{Set}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8af\/613\/530\/8af6135303f850350f917f2b2e11fefe.svg\" width=\"119\" height=\"18\"\/>, \u0433\u0434\u0435 <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\"\\star^{op}\" alt=\"\\star^{op}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/65d\/f6f\/2be\/65df6f2bec7ee6edc2b86c55a2bbaac4.svg\" width=\"25\" height=\"17\"\/> \u0435\u0441\u0442\u044c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f, \u0434\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u0438\u043f\u0430\u043c (\u043e\u0431\u044a\u0435\u043a\u0442\u044b \u2013 \u0442\u0435 \u0436\u0435 \u0442\u0438\u043f\u044b, \u0447\u0442\u043e \u0438 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438, \u043d\u043e \u0432\u0441\u0435 \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u044b-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u043b\u043e\u0436\u043d\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443).<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439. \u041d\u043e \u0432\u0441\u0451 \u0436\u0435, \u0447\u0442\u043e \u0434\u0430\u044e\u0442 \u0432\u0441\u0435 \u044d\u0442\u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430\u043c?<\/p>\n<p>\u0422\u0435\u043e\u0440\u0438\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u0437\u0430\u0440\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u043a\u0430\u043a \u0440\u0430\u0437\u0434\u0435\u043b \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0438 \u0441 \u0446\u0435\u043b\u044c\u044e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u043a\u0430\u043a \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0432\u0448\u0438\u0445 \u0442\u0430\u043c \u043f\u043e\u043d\u044f\u0442\u0438\u0439, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445. \u041e\u0434\u0438\u043d \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0437\u0430\u0434\u0430\u0447 \u0442\u043e\u043f\u043e\u043b\u043e\u0433\u0438\u0438 \u0441\u0432\u044f\u0437\u0430\u043d \u0441 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u043d\u0430\u0434 <em>\u043f\u0443\u0442\u044f\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438<\/em> \u2013 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u0438 \u0442.\u043f. \u041a \u044d\u0442\u043e\u043c\u0443 \u043a\u043b\u0430\u0441\u0441\u0443 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0435\u0433\u043e \u043f\u0443\u0442\u0438 \u043d\u0430 \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0433\u0440\u0430\u0444\u0435 \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0442\u043e\u0447\u043a\u0430\u043c\u0438. \u041d\u043e \u0432\u0435\u0434\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430\u043c \u2013 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0441\u0435\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u043d\u0430\u0439\u0442\u0438 \u043d\u0430\u0438\u043b\u0443\u0447\u0448\u0438\u0439 \u043f\u0443\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430!<\/p>\n<p>\u0422\u0435\u043e\u0440\u0438\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u043a\u0430\u043a \u0440\u0430\u0437 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0443\u0442\u044f\u043c\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439. \u041c\u043d\u043e\u0433\u0438\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f (\u0444\u0443\u043d\u043a\u0442\u043e\u0440\u044b, \u043c\u043e\u043d\u0430\u0434\u044b \u0438 \u0442.\u043f.) \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u043d\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 <em>\u043a\u043e\u043c\u043c\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/em> \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c \u2013 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u043d\u0430 \u044d\u0442\u0438\u0445 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430\u0445 \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442 \u043a \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u043c\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u043d\u0438\u0445 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439. \u041d\u043e, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0442\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0441\u0432\u043e\u0451 \u201c<a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A3%D0%BD%D0%B8%D0%B2%D0%B5%D1%80%D1%81%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D1%81%D0%B2%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%BE\" rel=\"noopener noreferrer nofollow\"><em>\u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e<\/em><\/a>\u201d, \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044e\u0449\u0435\u0435 \u201c\u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0441\u0442\u044c\u201c \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0430 \u0441\u0440\u0435\u0434\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0445. \u0418\u043c\u0435\u043d\u043d\u043e \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 <em>\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043d\u0430\u0438\u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439<\/em>.<\/p>\n<blockquote>\n<p>\u0422\u0435\u043e\u0440\u0438\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442, \u043f\u043e\u0447\u0435\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0435, \u0430 \u043d\u0435 \u0438\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430\u0438\u043b\u0443\u0447\u0448\u0438\u043c\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c.<\/p>\n<\/blockquote>\n<p>\u0423\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c (direct style) \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u201c\u0437\u0430\u043c\u0435\u0441\u0442\u0438 \u043f\u043e\u0434 \u043a\u043e\u0432\u0451\u0440\u201d, \u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u043d\u0430 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438 \u043b\u0438\u0448\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u041d\u043e \u043d\u0430\u0434\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043b\u044e\u0431\u0430\u044f \u0442\u0430\u043a\u0430\u044f \u043d\u0430\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0442\u043e\u0438\u0442 \u043d\u0430 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u043c \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0435 \u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0447\u0430\u0441\u0442\u043e \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442\u0441\u044f Scala-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441 \u0437\u0430\u0431\u0430\u0432\u043d\u044b\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c Cats. \u0420\u0435\u0441\u0443\u0440\u0441 \u042e\u0434\u0436\u0438\u043d\u0430 \u0419\u043e\u043a\u043e\u0442\u044b <a href=\"https:\/\/eed3si9n.com\/herding-cats\/\" rel=\"noopener noreferrer nofollow\">herding cats<\/a> \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u044f\u043c\u0438 \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0442\u0441\u044b\u043b\u0430\u0435\u0442 \u043a <a href=\"https:\/\/www.youtube.com\/watch?v=m_MaJDK3VNE\" rel=\"noopener noreferrer nofollow\">\u0448\u0443\u0442\u043e\u0447\u043d\u043e\u043c\u0443 \u0440\u0435\u043a\u043b\u0430\u043c\u043d\u043e\u043c\u0443 \u0440\u043e\u043b\u0438\u043a\u0443<\/a> (\u043e\u0442\u0441\u044b\u043b\u0430\u044e\u0449\u0435\u043c\u0443 \u043a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Herding_cats\" rel=\"noopener noreferrer nofollow\">\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439 \u0438\u0434\u0438\u043e\u043c\u0435<\/a>). \u041d\u043e \u0432\u0441\u0451 \u0436\u0435, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0431\u0435\u0440\u0451\u0442 \u043d\u0430\u0447\u0430\u043b\u043e \u043e\u0442 \u201c\u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439\u201d (<strong>Cat<\/strong>egorie<strong>s<\/strong>). \u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0431\u044b\u0432\u0430\u044e\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c <code>IO<\/code>, \u043d\u043e \u0438 \u0441 <code>ZIO<\/code>, <code>Future<\/code>, \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u044f \u0443\u0436\u0435 \u043e\u0431 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 <code>Option<\/code>, <code>List<\/code> \u0438 \u0442.\u043f.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u0440\u043c\u0438\u043d \u201c\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u201d \u0432\u0435\u0437\u0434\u0435, \u0433\u0434\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043e \u201c\u043c\u043e\u043d\u0430\u0434\u0430\u0445\u201d \u0438\u043b\u0438 \u201c\u0444\u0443\u043d\u043a\u0442\u043e\u0440\u0430\u0445\u201d. \u0422\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0442\u0435\u0440\u043c\u0438\u043d\u044b \u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u043f\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a <code>Option[_]<\/code>, \u0432\u043e\u043e\u0431\u0449\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e. \u0422\u0430\u043a\u0436\u0435 \u0444\u0443\u043d\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u043c\u043e\u043d\u0430\u0434\u0430\u043c\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0442\u0438\u043f\u043e\u0432 \u2013 \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0447\u0442\u043e \u201c\u043a\u043b\u0430\u0441\u0441\u044b\u201d, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c, \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0436\u0435 <code>Option<\/code>, \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432 <code>Functor[Option]<\/code>, <code>Moand[Option]<\/code>. \u0418 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f (\u043a\u043e\u0438 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c <em>\u0440\u0430\u0437\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/em> \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0442\u0438\u043f\u043e\u0432!) \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u043c\u043e\u043d\u0430\u0434\u0430\u043c\u0438. \u0414\u043b\u044f \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0445 \u0436\u0435 \u0442\u0438\u043f\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u0447\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0440\u043c\u0438\u043d <em>\u043f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0442\u0438\u043f\u043e\u0432<\/em>. \u041f\u0440\u0438\u0447\u0451\u043c, \u044d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043a\u043e\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043d\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c, \u043d\u043e \u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043d\u044b\u043c \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u043c \u0442\u0438\u043f\u0430\u043c \u2013 \u0442\u0430\u043a\u0443\u044e \u043f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e \u0431\u0443\u0434\u0443\u0442 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0442\u044c \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0443\u0436\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0442\u043e\u0440\u044b.<\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u0437\u043e\u0440 \u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u0435\u0439. \u0417\u0434\u0435\u0441\u044c \u0436\u0435 \u043f\u043e\u043a\u0430 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0443 \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/305018\/\" rel=\"noopener noreferrer nofollow\">\u0445\u0430\u0431\u0440-\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044b<\/a> (\u0441\u043c. \u0441\u0441\u044b\u043b\u043a\u0438 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0438 \u0441\u0430\u043c\u0443 \u0441\u0442\u0430\u0442\u044c\u044e) \u043f\u0435\u0440\u0432\u044b\u0445 \u0433\u043b\u0430\u0432 \u043a\u043d\u0438\u0433\u0438 \u201c\u0422\u0435\u043e\u0440\u0438\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u043e\u0432\u201d \u0411\u0430\u0440\u0442\u043e\u0448\u0430 \u041c\u0438\u043b\u0435\u0432\u0441\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/cit\/articles\/313254\/\" rel=\"noopener noreferrer nofollow\">\u0422\u0435\u043e\u0440\u0438\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u043d\u0430 JavaScript. \u0427\u0430\u0441\u0442\u044c 1. \u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432<\/a> \u2013 \u0442\u0443\u0442 \u0445\u043e\u0440\u043e\u0448\u0438\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438, \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0435, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u201c\u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u201d;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/445488\/\" rel=\"noopener noreferrer nofollow\">\u041c\u043e\u043d\u0430\u0434\u044b \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u043e\u0432 (\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439)<\/a> \u2013 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043d\u0430 Hakell, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u0445 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0439;<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0449\u0451 \u043f\u043e\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043a\u043d\u0438\u0433\u0443 \u0421\u0435\u0440\u0433\u0435\u044f \u0412\u0438\u043d\u0438\u0446\u043a\u043e\u0433\u043e <a href=\"https:\/\/github.com\/winitzki\/sofp\/releases\/download\/v0.11.2\/sofp-draft.pdf\" rel=\"noopener noreferrer nofollow\">The Science of Functional Programming<\/a> \u2013 \u044d\u0442\u043e \u0432\u0435\u0440\u0441\u0438\u044f 2021 \u0433\u043e\u0434\u0430, \u0430 \u0431\u043e\u043b\u0435\u0435 \u0441\u0432\u0435\u0436\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0441\u0430\u043c\u043e\u043c\u0443 <a href=\"https:\/\/leanpub.com\/sofp\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0441\u0442\u0438<\/a>, \u0438\u043b\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0437 <a href=\"https:\/\/github.com\/winitzki\/sofp\/tree\/master\/sofp-src\" rel=\"noopener noreferrer nofollow\">\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 \u043d\u0430 GitHub<\/a>.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u201c\u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b\u201d \u0441 \u0441\u0430\u043c\u044b\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u0440\u0430\u043a\u0443\u0440\u0441\u043e\u0432. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u0440\u043e\u044f\u0441\u043d\u0438\u043b\u0438, \u043a\u0430\u043a \u043e\u043d\u0438 \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435, \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0438 \u043d\u0430\u0434\u0451\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u044d\u0442\u043e\u0442 \u043e\u0431\u0437\u043e\u0440 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044e \u043d\u0435 \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u0438 \u0430\u0432\u0442\u043e\u0440\u0443 ?.<\/p>\n<\/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\/807495\/\"> https:\/\/habr.com\/ru\/articles\/807495\/<\/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<figure class=\"full-width\">\n<div><figcaption>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u043c \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430!<\/figcaption><\/div>\n<\/figure>\n<p><a class=\"anchor\" name=\"container_programming\" id=\"container_programming\"><\/a><\/p>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043e\u0431\u0437\u043e\u0440\u0430 \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e, \u043a\u0430\u043a \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0424\u041f-\u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u201c\u0447\u0438\u0441\u0442\u043e\u0433\u043e\u201d \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u201c\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445\u201d \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c. \u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u0430 \u0440\u043e\u043b\u044c \u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u0432 \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043d\u0430\u0434 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u0437\u043e\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/\" rel=\"noopener noreferrer nofollow\">\u0427\u0430\u0441\u0442\u044c 1<\/a><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/#generic_types\" rel=\"noopener noreferrer nofollow\">\u041e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/#type_constructors\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0442\u0438\u043f\u043e\u0432<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/#polymorphic_types\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0435 \u0442\u0438\u043f\u044b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807467\/#higher_tyeps\" rel=\"noopener noreferrer nofollow\">\u0422\u0438\u043f\u044b \u0432\u044b\u0441\u043e\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807485\" rel=\"noopener noreferrer nofollow\">\u0427\u0430\u0441\u0442\u044c 2<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807485\/#type_classes\" rel=\"noopener noreferrer nofollow\">\u041a\u043b\u0430\u0441\u0441\u044b \u0442\u0438\u043f\u043e\u0432<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807485\/#container_types\" rel=\"noopener noreferrer nofollow\">\u0422\u0438\u043f\u044b-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0427\u0430\u0441\u0442\u044c 3 (\u0434\u0430\u043d\u043d\u0430\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f) <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807495\/#container_programming\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u043a\u0430\u043a \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/807495\/#subcategories_of_types\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0442\u0438\u043f\u043e\u0432 (\u0432\u043c\u0435\u0441\u0442\u043e \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f)<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p><a href=\"#container_programming\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u043a\u0430\u043a \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#traditioal_di\" rel=\"noopener noreferrer nofollow\">\u0422\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#reader\" rel=\"noopener noreferrer nofollow\">\u201c\u0427\u0438\u0442\u0430\u0442\u0435\u043b\u044c\u201d<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#free\" rel=\"noopener noreferrer nofollow\">\u0421\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#continuations\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0438 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u044b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#tagless_final\" rel=\"noopener noreferrer nofollow\">Tagless Final<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#arrows\" rel=\"noopener noreferrer nofollow\">\u041a\u043b\u0435\u0439\u0441\u043b\u0438 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0442\u0440\u0435\u0301\u043b\u043a\u0438<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#subcategories_of_types\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0442\u0438\u043f\u043e\u0432 (\u0432\u043c\u0435\u0441\u0442\u043e \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f)<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<h3>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u043a\u0430\u043a \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/h3>\n<p>\u0421\u043b\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u0435\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u0438 \u043f\u043e\u043c\u0435\u043d\u044c\u0448\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, \u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435 \u0442\u0430\u043a\u0438\u0435 <em>\u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435<\/em> \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0447\u0430\u0441\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u201c\u0430\u043b\u0433\u0435\u0431\u0440\u0430\u043c\u0438\u201d. \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 (\u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0432\u0441\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b) \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041d\u043e, \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0438\u0445 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p><a class=\"anchor\" name=\"traditioal_di\" id=\"traditioal_di\"><\/a><\/p>\n<h4>\u0422\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434<\/h4>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u0441\u0430\u043c\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0445 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043a\u043e\u0433\u0434\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u201c\u0432 \u043b\u043e\u0431\u201d \u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445. \u0422\u0435\u0440\u043c\u0438\u043d \u201c\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u201d \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u0435\u043d \u2013 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u201c\u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f\u201d \u0438\u0437 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043f\u0440\u0438\u0447\u0451\u043c, \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e, \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0444\u0430\u0439\u043b\u0435, \u0431\u0435\u0437 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u043a \u0446\u0435\u043b\u0435\u0432\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443.<\/p>\n<p>\u041f\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u201c\u0441\u0435\u0440\u0432\u0438\u0441\u044b\u201d \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u0438, \u0438 \u0438\u0445 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445-\u043e\u0434\u0438\u043d\u043e\u0447\u043a\u0430\u0445, \u043d\u0435 \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u044f\u0441\u044c \u043e \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u042d\u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438\u0434\u0435\u0435 \u201c\u043e\u0442\u043a\u0430\u0437\u0430 \u043e\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439\u201d, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u043a\u0430\u043a \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u0430 \u043d\u0435 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435. \u041d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0442 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435 \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0430\u0440\u0443\u0448\u0430\u0435\u0442 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u201c<a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%B8%D0%BD%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D0%B8_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B5%D0%B9\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0432\u0435\u0440\u0441\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/a>\u201d, \u0432\u043d\u043e\u0441\u044f \u0432 \u043a\u043e\u0434 \u0438\u0437\u043b\u0438\u0448\u043d\u044e\u044e \u0441\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u044e \u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0436\u043d\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430 \u201c<a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%BE%D1%82%D0%BA%D1%80%D1%8B%D1%82%D0%BE%D1%81%D1%82%D0%B8\/%D0%B7%D0%B0%D0%BA%D1%80%D1%8B%D1%82%D0%BE%D1%81%D1%82%D0%B8\" rel=\"noopener noreferrer nofollow\">\u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438\/\u0437\u0430\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438<\/a>\u201d \u0438, \u043a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435, \u0438\u0437\u0434\u0435\u0440\u0436\u043a\u0430\u043c \u0432 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<p>\u0412 \u041e\u041e\u041f \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u0442\u043e\u043d\u043e\u043c \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0432 \u0432\u0438\u0434\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (<code>trait<\/code> \u0432 Scala), \u043a\u043b\u0430\u0441\u0441\u044b-\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0441\u0432\u043e\u0451\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435:<\/p>\n<pre><code class=\"scala\">trait Service1 { def func1(d: Double): Int    } trait Service2 { def func2(i: Int)   : String } trait Service3 { def func3(d: Double): String }  \/\/ \"\u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044f\" \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 final case class Service3Impl(srv1: Service1, srv2: Service2) extends Service3:   override def func3(d: Double) = srv2.func2(srv1.func1(d))<\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Service3<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 <code>func1<\/code> \u0438 <code>func2<\/code> \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 <code>Service1<\/code> \u0438 <code>Service2<\/code>. \u041d\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u0442\u0443 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e <em>\u0441\u043f\u0435\u0440\u0432\u0430<\/em> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/p>\n<pre><code class=\"scala\">val srv1: Service1 = ??? val srv2: Service2 = ???  val srv3: Service3 = Service3Impl(srv1, srv2) srv3.func3(4.2)<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0439 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0435\u0439 \u0442\u0430\u043a\u043e\u0439 \u043d\u0430\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u201c\u0432\u0441\u043a\u0438\u043f\u0430\u043d\u0438\u044e\u201d \u043a\u043e\u0434\u0430 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438. \u0412 Scala \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/github.com\/softwaremill\/macwire\" rel=\"noopener noreferrer nofollow\">MacWire<\/a> \u2013 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442 \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0438\u0449\u0443\u0442 \u0438 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432\u0434\u0440\u0443\u0433 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430, \u043e\u0431 \u044d\u0442\u043e\u043c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<p>\u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <a href=\"https:\/\/habr.com\/ru\/articles\/350708\/#start_DI_containers\" rel=\"noopener noreferrer nofollow\"><em>DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432<\/em><\/a> (dependency injection container). \u0422\u0443\u0434\u0430 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u044b-\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0430 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u043d\u0430 <em>\u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e \u0442\u0438\u043f\u0443<\/em> \u043a\u0430\u043a\u043e\u0433\u043e-\u043b\u0438\u0431\u043e \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441\u0430\u043c \u0441\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u0443\u0435\u0442 \u044d\u0442\u043e\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0441\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 (\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u044d\u0442\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0438 \u0442.\u043f.). \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u043c\u043d\u043e\u0433\u0438\u0445 DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0436\u0438\u0437\u043d\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443, \u0438\u043b\u0438 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u0437 \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438. \u0422\u0430\u043a\u0436\u0435 \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0437\u0430\u0449\u0438\u0449\u0430\u044e\u0442 \u043e\u0442 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u0432\u0441\u0435\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f <em>\u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/em>. \u0417\u043d\u0430\u0447\u0438\u0442 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438, \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c.<\/p>\n<p>\u0412 Scala \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 DI-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c <em>\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438<\/em>. \u041c\u0435\u0445\u0430\u043d\u0438\u0437\u043c <em>\u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0435\u0440\u043c\u043e\u0432<\/em> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044f\u0432\u043d\u043e \u0438\u043b\u0438 \u043d\u0435\u044f\u0432\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430:<\/p>\n<pre><code class=\"scala\">given Service1 = new Service1 { override def func1(d: Double) = ??? } given Service2 = new Service2 { override def func2(i: Int   ) = ??? }  object Service3:    def instance(using srv1: Service1, srv2: Service2) = Service3Impl(srv1, srv2)  Service3.instance.func3(4.2)<\/code><\/pre>\n<p>\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u0435 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u043a <code>instance<\/code> \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0439\u0434\u0435\u043d\u044b \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0438 \u043d\u0435\u044f\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u043a\u0430\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 <code>Service1<\/code> \u0438 <code>Service2<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u044d\u0442\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c <code>using<\/code>. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043f\u043e \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 <code>instance<\/code> \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432, \u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432\u044b\u0434\u0430\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u2013 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u044f\u0437\u044b\u043a\u0430 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u043f\u0440\u0438\u0447\u0451\u043c \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432!<\/p>\n<details class=\"spoiler\">\n<summary>Cake pattern<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u0442\u0435\u0445\u043d\u0438\u043a\u0438, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0445 \u0442\u0438\u043f\u0430\u0445, \u043d\u043e \u0440\u0430\u0434\u0438 \u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u0441\u0442\u043e\u0438\u0442 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0443\u044e \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/www.baeldung.com\/scala\/cake-pattern\" rel=\"noopener noreferrer nofollow\">Cake pattern<\/a>. \u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u0442\u0440\u0435\u0439\u0442\u044b \u0441 \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438, \u0430 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044f \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0442\u0435\u043c\u0438 \u0441\u0430\u043c\u044b\u043c\u0438 \u0442\u0440\u0435\u0439\u0442\u0430\u043c\u0438. Cake-pattern \u0431\u0430\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u0438\u0437\u043c\u0435 \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u0432, \u043d\u043e \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u043e\u0431 \u044d\u0442\u043e\u043c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0438\u043c\u0435\u0435\u0442 \u0440\u044f\u0434 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432 (\u0441\u043c., \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0442\u0430\u0442\u044c\u044e <a href=\"https:\/\/kubuszok.com\/2018\/cake-antipattern\/\" rel=\"noopener noreferrer nofollow\">Cake antipattern<\/a>), \u0438 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f.<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0443\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0448\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0438\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u0422\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u044b\u0448\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u043c, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u201c\u0447\u0438\u0441\u0442\u0430\u044f\u201d \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u044d\u0444\u0444\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0442.\u043f. \u0422\u0443\u0442 \u0432\u044b\u0440\u0443\u0447\u0430\u044e\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438.<\/p>\n<p>\u0412 Scala \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u044f\u0432\u043b\u044f\u043b\u0441\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 <code>Future<\/code>. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u0442\u043e\u043a\u0430\u043c, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0441\u043d\u0438\u0436\u0430\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430. \u041d\u043e \u0435\u0433\u043e \u201c\u0436\u0430\u0434\u043d\u044b\u0439\u201d \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440 \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u042d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043c\u043e\u0433\u0443\u0442 \u0440\u0435\u0448\u0438\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u201c\u043b\u0435\u043d\u0438\u0432\u044b\u0435\u201d \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u043a\u0430\u043a <code>IO<\/code> \u0438\u0437 <a href=\"https:\/\/typelevel.org\/cats\/\" rel=\"noopener noreferrer nofollow\">Cats<\/a>, <code>ZIO<\/code> \u0438\u0437 <a href=\"https:\/\/zio.dev\/\" rel=\"noopener noreferrer nofollow\">\u043e\u0434\u043d\u043e\u0438\u043c\u0451\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/a>, <code>Task<\/code> \u0438\u0437 \u0447\u0443\u0442\u044c \u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"https:\/\/monix.io\/\" rel=\"noopener noreferrer nofollow\">Monix<\/a>.<\/p>\n<p>\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u043e\u0441\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u044b \u0442\u0430\u043a\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0440\u0430\u043d\u0435\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0447\u0430\u0441\u0442\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u0430\u0445 \u0442\u0438\u043f\u043e\u0432, \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u0442\u0430\u043a\u0438\u0445:<\/p>\n<pre><code class=\"scala\">type Functor    [F[_]] = [A, B] =>  (A =>   B)  => (F[A] => F[B]) \/\/ Lift type Applicative[F[_]] = [A, B] => F[A =>   B]  => (F[A] => F[B]) \/\/ Lift &amp; Zip2 type Monad      [F[_]] = [A, B] =>  (A => F[B]) => (F[A] => F[B]) \/\/ Lift &amp; Flatten<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0445\u043e\u0436\u0435\u0441\u0442\u044c \u044d\u0442\u0438\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u0430\u0446\u0435\u043b\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0438\u0445 \u043d\u0430 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0451\u043d\u043d\u044b\u043c \u043e\u0434\u043d\u0438\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c <code>F[_]<\/code>. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, <code>Applicative<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a <code>Monad<\/code> \u2013 \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435. \u042d\u0442\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c <code>Monad<\/code> \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0432\u044b\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0443, \u0438 \u0441\u0431\u043e\u0439 \u0432 \u043b\u044e\u0431\u043e\u043c \u0437\u0432\u0435\u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u0442 \u043a \u0435\u0451 \u0440\u0430\u0437\u0440\u044b\u0432\u0443, \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044b. \u0412\u043e\u0442 \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430 \u0431\u0430\u0437\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>IO<\/code>:<\/p>\n<pre><code class=\"scala\">import cats.effect.IO import cats.syntax.all.* \/\/                                                \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0448\u0430\u0433\u043e\u0432 \u043d\u0435 \u0432\u0430\u0436\u043d\u044b def findTheKeys:        Clue          => IO[Keys]  = ??? def obtainPart1:        Keys          => IO[Part1] = ??? def obtainPart2:        Keys          => IO[Part2] = ??? def completeThePuzzle: (Part1, Part2) => Treasure  = ???  def findTheTreasure(someClue: Clue) =   findTheKeys(someClue)     .flatMap(keys => obtainPart1(keys) product obtainPart2(keys))      .map(completeThePuzzle.tupled)<\/code><\/pre>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0442\u0438\u043f\u043e\u0432 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>IO<\/code>:<\/p>\n<ul>\n<li>\n<p><code>map<\/code>  <code>Functor<\/code>,<\/p>\n<\/li>\n<li>\n<p><code>product<\/code>  <code>Applicative<\/code>,<\/p>\n<\/li>\n<li>\n<p><code>flatMap<\/code>  <code>Monad<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e\u0442 \u0431\u043e\u043b\u0435\u0435 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>for<\/code>-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"scala\">def findTheTreasure(someClue: Clue) =   for {     keys  &lt;- findTheKeys(someClue)     part1 &lt;- obtainPart1(keys)     part2 &lt;- obtainPart2(keys)   } yield completeThePuzzle(part1, part2)<\/code><\/pre>\n<p><code>For<\/code>-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u201c\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0430\u0445\u0430\u0440\u201d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u0435\u0434\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0442\u0435\u0445 \u0436\u0435 <code>map<\/code>, <code>flatMap<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0437\u043e\u0432 <code>map<\/code> \u0441\u043f\u0440\u044f\u0442\u0430\u043d \u0437\u0434\u0435\u0441\u044c \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u0435 \u0441 <code>yield<\/code>, \u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 <code>Applicative<\/code> \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u044b \u2013 \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 <code>flatMap<\/code> \u0438, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0443\u0434\u0430\u0441\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <code>part1<\/code>, \u0442\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 <code>part2<\/code> \u0434\u0430\u0436\u0435 \u043d\u0435 \u043d\u0430\u0447\u043d\u0451\u0442\u0441\u044f.<\/p>\n<p>\u041a\u0430\u043a\u043e\u0439 \u0431\u044b \u0441\u0442\u0438\u043b\u044c \u043d\u0438 \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d, \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0441\u0443\u0442\u044c \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0435\u0439 \u2013 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u043d\u044a\u0435\u043a\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f (\u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e, \u043d\u0435\u044f\u0432\u043d\u043e) \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0432 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 (\u0438, \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u0447\u0438\u0441\u0442\u043e\u0439!) \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0435\u0440\u043c\u043e\u0432 \u0434\u043b\u044f \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 <code>Future\/IO<\/code>\/<code>ZIO<\/code>\/<code>Task<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f Scala-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0438, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0435 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439. \u0414\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432.<\/p>\n<p><a class=\"anchor\" name=\"reader\" id=\"reader\"><\/a><\/p>\n<h4>\u201c\u0427\u0438\u0442\u0430\u0442\u0435\u043b\u044c\u201d<\/h4>\n<p>\u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0438\u0445 \u0432 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443<\/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-373550","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/373550","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=373550"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/373550\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=373550"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=373550"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=373550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}