{"id":301611,"date":"2020-04-09T21:00:23","date_gmt":"2020-04-09T21:00:23","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=301611"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=301611","title":{"rendered":"\u0420\u0430\u0434\u043e\u0441\u0442\u0438 \u0438 \u0433\u043e\u0440\u0435\u0441\u0442\u0438 \u043f\u043e\u0431\u0435\u0434 \u043d\u0430\u0434 C: \u0434\u0435\u043b\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0435\u0442\u043a\u0443 \u0438\u0437 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430 wc \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/496370\/\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440.<\/p>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, <a href=\"https:\/\/habr.com\/post\/489136\/\">\u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437<\/a> \u043c\u044b \u044d\u043c\u043f\u0438\u0440\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u043a\u0430\u0437\u0430\u043b\u0438, \u0447\u0442\u043e \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0430\u043a\u0438\u0439 \u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439 wc, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 wc \u0438\u0437 GNU Coreutils. \u041f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0434\u0435\u043b\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0447\u0435\u0441\u0442\u043d\u043e\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435: \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0435 \u0443\u043c\u0435\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0431\u0430\u0439\u0442, \u0441\u0442\u0440\u043e\u043a \u0438 \u0441\u043b\u043e\u0432, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 wc \u043a\u0443\u0434\u0430 \u043c\u043e\u0449\u043d\u0435\u0435: \u043e\u043d \u0438\u043c\u0435\u0435\u0442 \u0435\u0449\u0451 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043e\u043f\u0446\u0438\u0438, \u0443\u043c\u0435\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c \u0438\u0437 stdin\u2026 \u041a\u043e\u0440\u043e\u0447\u0435, \u0443 \u043d\u0430\u0441 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0438\u0433\u0440\u0443\u0448\u043a\u0430.<\/p>\n<p>  <\/p>\n<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c. \u041d\u0430\u0448\u0430 \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u2014 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u0410 \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f \u043a \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0432\u044b\u0434\u0435\u043b\u044f\u044f \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u044e\u043d\u0438\u0442.<\/p>\n<p>  <\/p>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 <a href=\"https:\/\/github.com\/coreutils\/coreutils\/blob\/master\/src\/wc.c\" rel=\"nofollow\">C-\u0432\u0435\u0440\u0441\u0438\u044e<\/a> \u2014 \u043d\u0443, \u043b\u0438\u0447\u043d\u043e \u044f \u0431\u044b \u043d\u0435 \u043d\u0430\u0437\u0432\u0430\u043b \u044d\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u0446\u043e\u043c \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0433\u043e \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u043c \u0432\u0441\u0451 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 370 \u0441\u0442\u0440\u043e\u043a. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0430\u0440\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/rm\/rk\/d0\/rmrkd0k9gjyumqz6fmjbxsooovi.png\"><\/div>\n<p>  <\/p>\n<p><em>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0421-\u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0435 \u0432\u043b\u0435\u0437\u043b\u0430 \u043d\u0430 4k-\u044d\u043a\u0440\u0430\u043d \u0432 \u043f\u043e\u0440\u0442\u0440\u0435\u0442\u043d\u043e\u0439 \u043e\u0440\u0438\u0435\u043d\u0442\u0430\u0446\u0438\u0438 4-\u043c \u0448\u0440\u0438\u0444\u0442\u043e\u043c.<\/em><\/p>\n<p>  <\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0439 \u043c\u043e\u0434\u0443\u043b\u044f\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u044b, \u0441\u0440\u0435\u0434\u0438 \u043f\u0440\u043e\u0447\u0435\u0433\u043e:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u044b\u0440\u0430\u0437\u0438\u043c \u0438\u0434\u0435\u044e, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0432\u0440\u043e\u0434\u0435 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0447\u0438\u0441\u043b\u0430 \u0431\u0430\u0439\u0442 \u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0435\u0435 \u043d\u0430 \u0432\u0441\u0451\u043c \u0432\u0445\u043e\u0434\u0435 \u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0431\u0430\u0439\u0442;<\/li>\n<li>\u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u043d\u0430\u0441\u043b\u0430\u0436\u0434\u0430\u044f\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043d\u0438\u0445 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 (\u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 local reasoning);<\/li>\n<li>\u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u043e\u0432, \u043d\u0430\u0441\u043b\u0430\u0436\u0434\u0430\u044f\u0441\u044c local reasoning&#8217;\u043e\u043c \u0435\u0449\u0451 \u0440\u0430\u0437;<\/li>\n<li>\u0438\u0441\u043f\u044b\u0442\u0430\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0447\u0442\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u043a\u0438, \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439, \u043d\u043e \u0444\u0435\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u043e\u0440\u043c\u043e\u0437\u044f\u0449\u0438\u0439 \u043a\u043e\u0434;<\/li>\n<li>\u043f\u043e\u0438\u0433\u0440\u0430\u0435\u043c \u0441 Template Haskell;<\/li>\n<li>\u043f\u043e\u043b\u044e\u0431\u0443\u0435\u043c\u0441\u044f (\u043d\u0435)\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0441\u0442\u044c\u044e \u0438 (\u043d\u0435)\u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430.<\/li>\n<\/ul>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>\u041d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0435\u043c \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u043e\u0441\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">{-# LANGUAGE Strict #-} {-# LANGUAGE RecordWildCards #-}  module Data.WordCount where  import qualified Data.ByteString.Lazy as BS  data State = State   { bs :: Int   , ws :: Int   , ls :: Int   , wasSpace :: Int   }  wc :: BS.ByteString -&gt; (Int, Int, Int) wc s = (bs, ws + 1 - wasSpace, ls)   where     State { .. } = BS.foldl' go (State 0 0 0 1) s      go State { .. } c = State (bs + 1) (ws + addWord) (ls + addLine) isSp       where         isSp | c == 32 || c - 9 &lt;= 4 = 1              | otherwise = 0         addLine | c == 10 = 1                 | otherwise = 0         addWord = (1 - wasSpace) * isSp {-# INLINE wc #-}<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u0443\u0441\u043e\u0447\u043a\u0438, \u0441\u0447\u0438\u0442\u0430\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u0439\u0442, \u0441\u043b\u043e\u0432 \u0438 \u0441\u0442\u0440\u043e\u043a. \u041a\u0430\u043a \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f?<\/p>\n<p>  <\/p>\n<h1 id=\"kompozabelnye-levye-svyortki\">\u041a\u043e\u043c\u043f\u043e\u0437\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435 \u043b\u0435\u0432\u044b\u0435 \u0441\u0432\u0451\u0440\u0442\u043a\u0438<\/h1>\n<p>  <\/p>\n<p>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0432\u044b\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0441\u0432\u0451\u0440\u0442\u043a\u0430. \u0412 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043e\u0431 \u044d\u0442\u043e\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0434\u0430\u0436\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>BS.foldl'<\/code>!<\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/hackage.haskell.org\/package\/foldl\" rel=\"nofollow\">foldl<\/a>, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u00ab\u043a\u043e\u043c\u043f\u043e\u0437\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0445, \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u0445 \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u043b\u0435\u0432\u044b\u0445 \u0441\u0432\u0451\u0440\u0442\u043e\u043a\u00bb. \u042d\u0442\u043e \u0440\u043e\u0432\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e! \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0432 \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0434\u0430\u0436\u0435 \u0435\u0441\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 <a href=\"http:\/\/hackage.haskell.org\/package\/foldl-1.4.6\/docs\/Control-Foldl-ByteString.html\" rel=\"nofollow\">\u043c\u043e\u0434\u0443\u043b\u044c<\/a> \u0434\u043b\u044f \u0441\u0432\u0451\u0440\u0442\u043e\u043a \u043f\u043e <code>ByteString<\/code>. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0432 \u044d\u0442\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0438\u0437 \u0442\u0440\u0451\u0445 \u043d\u0443\u0436\u043d\u044b\u0445 \u043d\u0430\u043c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a: \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u0439\u0442 \u0440\u0430\u0432\u043d\u043e \u0434\u043b\u0438\u043d\u0435 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 (\u0442\u043e \u0435\u0441\u0442\u044c, <code>length<\/code> \u0432 \u044d\u0442\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435), \u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>count<\/code> (\u0447\u0435\u0440\u0435\u0437 <code>count 10<\/code>). \u041f\u043e\u0445\u043e\u0436\u0435, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u0451\u0440\u0442\u043a\u0443 \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0441\u043b\u043e\u0432, \u0438 \u043c\u044b \u0432 \u0434\u0430\u043c\u043a\u0430\u0445!<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0432\u0451\u0440\u0442\u043a\u0443, \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u043d\u0430\u0448\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u044c \u0438\u0437 \u043d\u0435\u0451 \u0432\u0441\u0451 \u043b\u0438\u0448\u043d\u0435\u0435. \u0412\u043e\u0442 \u0442\u0430\u043a \u0432 \u0438\u0442\u043e\u0433\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">{-# LANGUAGE Strict #-}  import qualified Control.Foldl as L import qualified Data.ByteString as BS  data WordState = WordState { ws :: Int, wasSpace :: Int }  wordsCount :: L.Fold BS.ByteString Int wordsCount = L.Fold (BS.foldl' go) (WordState 0 1) (\\WordState { .. } -&gt; ws + 1 - wasSpace)   where     go WordState { .. } c = WordState (ws + addWord) isSp       where         isSp | c == 32 || c - 9 &lt;= 4 = 1              | otherwise = 0         addWord = (1 - wasSpace) * isSp<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e\u0433\u0434\u0430 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0431\u0430\u0439\u0442\u044b, \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0441\u043b\u043e\u0432\u0430 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">import qualified Control.Foldl.ByteString as BL  main :: IO () main = do   [path] &lt;- getArgs   contents &lt;- unsafeMMapFile path   let res = BL.fold ((,,) &lt;$&gt; BL.length &lt;*&gt; BL.count 10 &lt;*&gt; wordsCount) (BSL.fromStrict contents) :: (Int, Int, Int)   print res<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u043c\u043f\u043e\u0437\u0430\u0431\u0435\u043b\u044c\u043d\u043e! \u041d\u043e \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e?<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430\u0442\u044c \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u0441\u0442\u0435 (\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044f \u043f\u044f\u0442\u044c \u0440\u0430\u0437 \u043d\u0430 1.8-\u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442\u043e\u0432\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0435\u043c\u0441\u044f \u0432 <code>tmpfs<\/code>-\u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0434\u043b\u044f \u0443\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f IO, \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u044f \u043d\u0430\u0438\u043b\u0443\u0447\u0448\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442), \u0442\u043e \u043d\u0430 \u043c\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 2.5 \u0441\u0435\u043a\u0443\u043d\u0434. \u041a\u0441\u0442\u0430\u0442\u0438, \u043d\u0430\u0434\u043e \u0434\u043b\u044f \u0447\u0435\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043c\u0430\u0448\u0438\u043d\u0430 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043e\u043c, \u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u043f\u043e\u0441\u0442\u0435 (\u0445\u043e\u0442\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0447\u0442\u043e \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e <code>wc<\/code>, \u0447\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0443\u0441\u0438\u043b\u0438\u0439 \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u043d\u0430 \u043d\u0435\u0439 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e), \u0434\u0430 \u0438 \u043d\u0435\u0439 \u0435\u0441\u0442\u044c \u043a\u0443\u0447\u0430 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0448\u0443\u043c\u0430 \u0432\u0440\u043e\u0434\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0438\u043b\u0438 IDE, \u043d\u043e \u0434\u043b\u044f \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u0449\u0435\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u044b \u043e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0430\u0445 \u043a\u043e\u0434\u0430 \u0438 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438\u0434\u0435\u0438 \u043f\u043e\u0441\u0442\u0430 \u044d\u0442\u043e\u0433\u043e \u0445\u0432\u0430\u0442\u0438\u0442.<\/p>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, 2.5 \u0441\u0435\u043a\u0443\u043d\u0434. \u041f\u043e\u0447\u0442\u0438 \u0432\u0434\u0432\u043e\u0435 \u0445\u0443\u0436\u0435, \u0447\u0435\u043c \u0431\u044b\u043b\u043e \u0440\u0430\u043d\u044c\u0448\u0435.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u0438\u0448\u044c \u0434\u043b\u0438\u043d\u0443 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0432?<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">  let res = BL.fold ((,) &lt;$&gt; BL.length &lt;*&gt; wordsCount) contents :: (Int, Int)   print res<\/code><\/pre>\n<p>  <\/p>\n<p>1.55 \u0441\u0435\u043a\u0443\u043d\u0434. \u0425\u043c\u043c. \u0427\u0442\u043e \u043d\u0430\u0441\u0447\u0451\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0442\u0440\u043e\u043a?<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">  let res = BL.fold (BL.count 10) contents :: Int   print res<\/code><\/pre>\n<p>  <\/p>\n<p>1.05 \u0441\u0435\u043a\u0443\u043d\u0434.<\/p>\n<p>  <\/p>\n<p>\u0427\u0451\u0440\u0442. \u041e\u043d\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0430\u0434\u0434\u0438\u0442\u0438\u0432\u043d\u043e. \u041d\u043e \u043e\u043d\u043e <em>\u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e<\/em> \u0431\u044b\u0442\u044c \u0430\u0434\u0434\u0438\u0442\u0438\u0432\u043d\u043e! \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0442\u0440\u043e\u043a (\u0441\u0432\u043e\u0434\u044f\u0449\u0438\u0439\u0441\u044f \u043a \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0443 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 <code>'\\n'<\/code>) \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u0442\u043c\u0435\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0443\u0434\u0430 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u043b\u043e\u0432, \u043d\u043e \u043c\u044b \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c.<\/p>\n<p>  <\/p>\n<p>\u041f\u043b\u043e\u0445\u043e. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u0437\u0430\u0441\u0443\u0447\u0438\u043c \u0440\u0443\u043a\u0430\u0432\u0430 \u0438 \u0437\u0430\u043b\u0435\u0437\u0435\u043c \u0432 \u043a\u0438\u0448\u043a\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <code>foldl<\/code>.<\/p>\n<p>  <\/p>\n<p><code>foldl<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u041e\u043d \u0431\u0435\u0440\u0451\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u043d\u043a \u0432\u0445\u043e\u0434\u0430 \u0438 \u0441\u043a\u0430\u0440\u043c\u043b\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u0441\u0432\u0451\u0440\u0442\u043e\u043a \u0432 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0442\u0440\u043e\u043a <code>foldl<\/code> \u0431\u0435\u0433\u0430\u0435\u0442 \u043f\u043e \u043b\u0435\u043d\u0438\u0432\u044b\u043c <code>ByteString<\/code>&#8216;\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0438\u0437\u043e\u043c\u043e\u0440\u0444\u043d\u044b \u0441\u043f\u0438\u0441\u043a\u0443 \u0441\u0442\u0440\u043e\u0433\u0438\u0445 <code>ByteString<\/code>&#8216;\u043e\u0432, \u043a\u0430\u0436\u0434\u0430\u044f \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u043d\u043a\u043e\u043c. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u0447\u0430\u043d\u043a\u0430 \u2014 256 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442, \u0447\u0442\u043e \u043d\u0435 \u0432\u043b\u0435\u0437\u0430\u0435\u0442 \u0432 L1-\u043a\u044d\u0448, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u044b \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d\u044b \u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0437\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 L2 \u0432 L1 (\u0438 \u0434\u0430\u0436\u0435 \u0437\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0438\u0437 L1 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b).<\/p>\n<p>  <\/p>\n<p>\u041c\u044b, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0447\u0430\u043d\u043a\u0430 \u0434\u043e 16-32 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043f\u043e\u043c\u0435\u0449\u0430\u043b\u0441\u044f \u0432 L1, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a <em>\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e<\/em>.<\/p>\n<p>  <\/p>\n<p>\u0418, \u0447\u0442\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0445\u0443\u0436\u0435, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u043f\u043e\u0445\u043e\u0436\u0435, \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f: \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b <code>BL.fold ((,) &lt;$&gt; wordsCount &lt;*&gt; wordsCount) contents<\/code> (\u0442\u043e \u0435\u0441\u0442\u044c, \u0434\u0432\u043e\u0439\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0441\u043b\u043e\u0432) <em>\u0432\u0434\u0432\u043e\u0435<\/em> \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 <code>BL.fold wordsCount contents<\/code>. \u0422\u0430\u043a \u0447\u0442\u043e \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043c\u044b \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d\u044b \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043d\u0435\u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043a\u0430\u043a \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u0442\u044c \u0441\u0432\u0451\u0440\u0442\u043a\u0438 \u00ab\u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443\u00bb, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u043e\u043f\u0446\u0438\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c&#8230;<\/p>\n<p>  <\/p>\n<h1 id=\"nashi-sobstvennye-svyortki\">\u041d\u0430\u0448\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0441\u0432\u0451\u0440\u0442\u043a\u0438<\/h1>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u0431\u0440\u043e\u0441\u0430\u0442\u044c\u0441\u044f \u043a \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0443 \u043a\u043e\u0434\u0430, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0435\u043c \u043e \u0434\u0438\u0437\u0430\u0439\u043d\u0435. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441\u0432\u0451\u0440\u0442\u043e\u043a \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0430\u043d\u0442\u0430\u0439\u043c-\u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c?<\/p>\n<p>  <\/p>\n<p>\u041f\u0443\u0441\u0442\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u00ab\u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u0435\u00bb \u0441\u0432\u0451\u0440\u0442\u043a\u0438 (\u0442\u043e \u0435\u0441\u0442\u044c, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438) <code>f1<\/code>, <code>f2<\/code>, <code>f3<\/code>, \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0443\u0436\u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f <code>f1<\/code> \u0438 <code>f3<\/code>. \u0414\u0443\u043c\u0430\u044e, \u0434\u0430\u0436\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u0435\u0449\u0451 \u0434\u043e\u043b\u0433\u043e \u0431\u0443\u0434\u0443\u0442 \u043d\u0435 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043c\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u0434 \u0432\u0440\u043e\u0434\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">  -- options \u2014 \u0441\u043f\u0438\u0441\u043e\u043a \u0431\u0443\u043b\u0435\u0432\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u044b\u043c \u0441\u0432\u0451\u0440\u0442\u043a\u0430\u043c   options &lt;- parseCliOptions    -- theFold \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0430\u044f \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f   let theFold = foldl' f (zip options [f1, f2, f3]) emptyFold   where     f acc (True, stat) = acc `compose` stat     f acc (False, _) = acc<\/code><\/pre>\n<p>  <\/p>\n<p>\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0441\u0432\u0451\u0440\u0442\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0443\u0442 \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0431\u044b\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u043c, \u0447\u0442\u043e \u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u2014 \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0432\u0441\u0451 \u044d\u0442\u043e \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0442\u0438\u043f\u043e\u0432. \u0425\u0430\u0441\u043a\u0435\u043b\u044c \u0432 \u0438\u0442\u043e\u0433\u0435 \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442 \u0442\u0438\u043f\u043e\u0432 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u043b\u044e\u0431\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u043d\u0430\u044f \u0447\u0435\u0440\u0435\u0437 \u0442\u0438\u043f\u044b, \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443.<\/p>\n<p>  <\/p>\n<h2 id=\"tipy-na-pomosch\">\u0422\u0438\u043f\u044b \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c<\/h2>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0432\u0451\u0440\u0442\u043a\u0443?<\/p>\n<p>  <\/p>\n<p>\u041e\u0434\u0438\u043d \u0434\u0440\u0443\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a \u0442\u0438\u043f\u0430\u043c \u0441\u043f\u043e\u0441\u043e\u0431 \u2014 \u0447\u0435\u0440\u0435\u0437 \u0442\u0430\u0439\u043f\u043a\u043b\u0430\u0441\u0441. \u0422\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043f\u043a\u043b\u0430\u0441\u0441\u044b, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0440\u0430\u0437\u0443 \u0443\u043f\u043e\u043c\u044f\u043d\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0442\u0438\u043f\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u043d\u0430 \u043d\u0438\u0445 \u043d\u0435 \u043e\u0442\u0432\u043b\u0435\u043a\u0430\u0442\u044c\u0441\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses, UndecidableInstances, FlexibleInstances #-} {-# LANGUAGE TypeFamilyDependencies, FunctionalDependencies, PolyKinds, DataKinds, GADTs, TypeOperators #-} {-# LANGUAGE ScopedTypeVariables #-}<\/code><\/pre>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0432\u0451\u0440\u0442\u043a\u043e\u0439-\u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u043e\u0439 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435? \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f,<\/li>\n<li>\u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u0448\u0430\u0433\u0430, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0435\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u0443,<\/li>\n<li>\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442-\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442,<\/li>\n<li>\u0442\u0438\u043f\u043e\u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u043e \u0437\u0430\u043f\u0438\u0448\u0435\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">class Statistic s res st | res -&gt; s, st -&gt; s                          , s -&gt; res, s -&gt; st                          where   initState :: st   extractState :: st -&gt; res   step :: st -&gt; Word8 -&gt; st<\/code><\/pre>\n<p>  <\/p>\n<p>\u0433\u0434\u0435 <code>s<\/code> \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 (\u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0448\u0442\u0443\u043a\u0430 \u0438\u0437 <code>DataKinds<\/code>), \u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0442\u0438\u043f\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u044d\u0442\u043e \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u043d\u0430\u0441 \u043e\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0432\u0441\u0435 \u0442\u0438\u043f\u044b-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0442\u0430\u0439\u043f\u043a\u043b\u0430\u0441\u0441\u0430 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435: \u0438\u043d\u0430\u0447\u0435 \u043d\u0430\u043c \u0431\u044b \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u0438\u0441\u0430\u0442\u044c<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">  initState :: proxy1 s -&gt; proxy2 res -&gt; st   extractState :: proxy s -&gt; st -&gt; res   step :: proxy1 s -&gt; proxy2 res -&gt; st -&gt; Word8 -&gt; st<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u043e\u0432, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u0430 \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u0430 \u0438\u0437 \u043d\u0438\u0445, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 \u0438 \u044f\u0441\u043d\u044b\u0435 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b.<\/p>\n<p>  <\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u0437\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043a\u0443\u0434\u0430 \u0431\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u044b\u043c\u0438 \u0438 \u043e\u0431\u0449\u0438\u043c\u0438 \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0442\u0438\u043f\u043e\u0432, \u0447\u0442\u043e \u0434\u0430\u043b\u043e \u0431\u044b \u0438\u043d\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0432 \u043e\u0434\u043d\u0443 \u0438\u0437 \u0441\u0442\u043e\u0440\u043e\u043d, \u043d\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a \u0447\u0435\u0440\u0435\u0437 \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0430\u0439\u043f\u043a\u043b\u0430\u0441\u0441 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043c\u043d\u0435 \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u044b\u043c \u0438 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0432 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435.<\/p>\n<p>  <\/p>\n<h3 id=\"statistiki-po-chankam\">\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043f\u043e \u0447\u0430\u043d\u043a\u0430\u043c<\/h3>\n<p>  <\/p>\n<p>\u041f\u043e\u043a\u0430 \u0432\u0441\u0451 \u0432\u0440\u043e\u0434\u0435 \u0431\u044b \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u043d\u043e \u043a\u043e\u0435-\u0447\u0435\u0433\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0443\u043c\u0430\u0435\u043c, \u043a\u0430\u043a \u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0431\u0430\u0439\u0442. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443, \u0442\u043e \u043d\u0430\u043c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u043e \u043f\u0440\u043e\u0431\u0435\u0433\u0430\u0442\u044c \u0432\u0441\u044e \u0441\u0442\u0440\u043e\u043a\u0443, \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u044f \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0437\u044f\u0442\u044c \u0434\u043b\u0438\u043d\u0443 \u0432\u0441\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0440\u0430\u0434\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0436\u0438\u0437\u043d\u0438, \u0441\u0432\u0435\u0434\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/3b3\/7f3\/0f2\/3b37f30f255db9e1e93d63099fa0d62c.svg\" alt=\"$O(n)$\" data-tex=\"inline\"><\/math> \u0434\u043e <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/655\/b80\/5d6\/655b805d68b4b00a4e90f64eefbc6f1c.svg\" alt=\"$O(1)$\" data-tex=\"inline\"><\/math>. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u0441\u043b\u043e\u0432 (\u0438\u043b\u0438, \u0447\u0442\u043e \u0435\u0449\u0451 \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0441\u0442\u0440\u043e\u043a\u0438) \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u043b\u0435\u0433\u043a\u043e \u0432\u044b\u0440\u0430\u0437\u0438\u043c\u043e\u0439 \u00ab\u0447\u0430\u043d\u043a\u043e\u0432\u043e\u0439\u00bb \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b (\u0435\u0441\u043b\u0438 \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0445\u0438\u0442\u0440\u043e\u0443\u043c\u043d\u044b\u0435 SIMD-\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0430\u043d\u0430\u043b\u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u043b\u044c\u043d\u043e \u0432\u043d\u0435 \u0442\u0435\u043c\u044b \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430). \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435 \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u043c \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438. \u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u0438\u0437 \u043d\u0438\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0447\u0430\u043d\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0442\u043e \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0442\u043e\u0436\u0435 \u0435\u0433\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442, \u0430 \u0438\u043d\u0430\u0447\u0435 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u0434\u043e \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430.<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0438 \u0447\u0430\u043d\u043a\u043e\u0432\u044b\u0439, \u0438 \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u043e? \u0417\u0434\u0435\u0441\u044c \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 GADT! \u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0438\u043f-\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f <em>\u0440\u0435\u0436\u0438\u043c\u0430 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430<\/em> \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u0438 \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c GADT \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u043c\u044b\u0441\u043b \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0436\u0438\u043c\u0430. \u0418\u043b\u0438 \u0432 \u043a\u043e\u0434\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">data StatCompTyOf = Chunked | ByteOnly  data StatComputation st compTy where   ChunkedComputation :: (st -&gt; Word8 -&gt; st)                      -&gt; (st -&gt; BS.ByteString -&gt; st)                      -&gt; StatComputation st 'Chunked   ByteOnlyComputation :: (st -&gt; Word8 -&gt; st)                       -&gt; StatComputation st 'ByteOnly<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c (\u0438 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0438\u0437\u043b\u043e\u0436\u0435\u043d\u0438\u0438) <code>BS<\/code> \u2014 \u043c\u043e\u0434\u0443\u043b\u044c, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0441\u0442\u0440\u043e\u0433\u0438\u043c \u0431\u0430\u0439\u0442\u043e\u0432\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u043c \u043d\u0430\u0448 \u043a\u043b\u0430\u0441\u0441 <code>Statistic<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0442\u0443\u0434\u0430 \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>comp<\/code> \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0432 \u043c\u0435\u0442\u043e\u0434 <code>step<\/code> \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043e\u0431\u0449\u0438\u0439 <code>computation<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">class Statistic s res st comp | res -&gt; s, st -&gt; s                               , s -&gt; res, s -&gt; st, s -&gt; comp                               where   initState :: st   extractState :: st -&gt; res   computation :: StatComputation st comp<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418 \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u043c \u0441\u043d\u043e\u0432\u0430 \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043b\u0438\u0431\u043e <code>s<\/code>, \u043b\u0438\u0431\u043e <code>res<\/code>, \u043b\u0438\u0431\u043e <code>st<\/code>, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445.<\/p>\n<p>  <\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044f\u0432\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043b\u0435\u0433\u043a\u043e \u043e\u0431\u043e\u0431\u0449\u0438\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0431\u043e\u043b\u044c\u0448\u0435\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0438\u0434\u043e\u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 SIMD-\u0443\u0441\u043a\u043e\u0440\u0435\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u043f\u043e 16-32 \u0431\u0430\u0439\u0442\u0430 \u0437\u0430 \u0440\u0430\u0437. \u041e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0438\u0437\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u044b \u043d\u0430 \u044d\u0442\u043e \u043e\u0442\u0432\u043b\u0435\u043a\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<\/p>\n<p>  <\/p>\n<h2 id=\"realizaciya-statistik\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a<\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u043a\u0438\u0435 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0447\u0438\u0441\u043b\u043e \u0431\u0430\u0439\u0442,<\/li>\n<li>\u0447\u0438\u0441\u043b\u043e (UTF-8)-\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432,<\/li>\n<li>\u0447\u0438\u0441\u043b\u043e \u0441\u043b\u043e\u0432,<\/li>\n<li>\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438,<\/li>\n<li>\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u043e\u043a.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0418\u043b\u0438 \u0432 \u043a\u043e\u0434\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">data Statistics = Bytes | Chars | Words | MaxLL | Lines deriving (Eq, Ord)<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0433\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u0434\u0430 \u0438 <code>wc<\/code> \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u2014 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Statistic<\/code>. \u0418, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a \u2014 \u043e\u0434\u043d\u043e \u0447\u0438\u0441\u043b\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043e\u0431\u0451\u0440\u0442\u043a\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">newtype Tagged a = Tagged Word64 deriving (Eq, Show, Num)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0437\u0434\u0435\u0441\u044c <code>a<\/code> \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043b\u0438\u0447\u0438\u0442\u044c <code>Tagged 'Bytes<\/code> \u043e\u0442 <code>Tagged 'Chars<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c\u0443\u044e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443: \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0431\u0430\u0439\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">instance Statistic 'Bytes (Tagged 'Bytes) (Tagged 'Bytes) 'Chunked where   initState = 0   extractState = id   computation = ChunkedComputation (\\st _ -&gt; st + 1) (\\st str -&gt; st + fromIntegral (BS.length str))<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0430\u043c\u043e\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u041c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c, \u0447\u0442\u043e <code>Bytes<\/code> \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 <code>Tagged 'Bytes<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438 \u0442\u0438\u043f\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0438 \u0442\u0438\u043f\u043e\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0447\u0430\u043d\u043a\u043e\u0432\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f.<\/li>\n<li>\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (\u0442\u043e \u0435\u0441\u0442\u044c, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u0439\u0442) \u0440\u0430\u0432\u043d\u043e 0.<\/li>\n<li>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0433\u043e \u2014 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0435\u0441\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/li>\n<li><code>computation<\/code> \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0447\u0430\u043d\u043a\u043e\u0432\u044b\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0441\u043a\u0430\u0437\u0430\u043b\u0438 <code>'Chunked<\/code> \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0448\u0430\u0433\u0430 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0447\u0451\u0442\u0447\u0438\u043a, \u0430 \u0447\u0430\u043d\u043a\u043e\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0443 \u0432\u0441\u044e \u0434\u043b\u0438\u043d\u0443 \u0432\u0445\u043e\u0434\u0430.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043a\u0443\u0447\u043d\u044b, \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u0438\u0445 \u0441\u043f\u0440\u044f\u0447\u0443 \u043f\u043e\u0434 \u0441\u043f\u043e\u0439\u043b\u0435\u0440, \u043d\u043e \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u0435\u0442\u0441\u044f   <\/p>\n<p>\u041f\u043e\u0434\u0441\u0447\u0451\u0442 \u0441\u0442\u0440\u043e\u043a \u0442\u043e\u0436\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442, \u0438 \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0442\u043e\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u0430\u043a \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0435, \u0442\u0430\u043a \u0438 \u0447\u0430\u043d\u043a\u043e\u0432\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">instance Statistic 'Lines (Tagged 'Lines) (Tagged 'Lines) 'Chunked where   initState = 0   extractState = id   computation = ChunkedComputation (\\st c -&gt; st + if c == 10 then 1 else 0) (\\st str -&gt; st + fromIntegral (BS.count 10 str))<\/code><\/pre>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u043d\u0430\u0441\u0447\u0451\u0442 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0441\u043b\u043e\u0432? \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0439 \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u0438 \u0437\u0430\u0438\u043c\u0441\u0442\u0432\u0443\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">data WordsState = WordsState { ws :: Word64, wasSpace :: Word64 }  instance Statistic 'Words (Tagged 'Words) WordsState 'ByteOnly where   initState = WordsState 0 1   extractState WordsState { .. } = Tagged (ws + 1 - wasSpace)   computation = ByteOnlyComputation step     where       step WordsState { .. } c = WordsState (ws + (1 - wasSpace) * isSp) isSp         where           isSp | c == 32 || c - 9 &lt;= 4 = 1                | otherwise = 0<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0441 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0442\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438, \u0447\u0442\u043e \u043c\u044b \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435. \u0427\u0442\u043e \u043d\u0430\u0441\u0447\u0451\u0442 \u043d\u043e\u0432\u0435\u043d\u044c\u043a\u0438\u0445 \u2014 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 UTF-8-\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0441\u0442\u0440\u043e\u043a\u0438?<\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e\u043c \u0436\u043e\u043d\u0433\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0431\u0438\u0442\u0430\u043c\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">instance Statistic 'Chars (Tagged 'Chars) (Tagged 'Chars) 'ByteOnly where   initState = 0   extractState = id   computation = ByteOnlyComputation $ \\cnt c -&gt;         cnt + 1 - fromIntegral (   ((c .&amp;. 0b10000000) `shiftR` 7)                                .&amp;. (1 - ((c .&amp;. 0b01000000) `shiftR` 6))                                )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043e\u043f\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438 UTF-8: \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0438\u043c\u0435\u0435\u0442 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0431\u0430\u0439\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0443 <code>10xxxxxx<\/code>. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c UTF-8 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u043d\u0430\u0441\u0447\u0451\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0441\u0442\u0440\u043e\u043a\u0438? \u0422\u0443\u0442 \u0432\u0441\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u043c \u0443\u0447\u0451\u0442\u0435 \u043d\u0435\u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0442\u0430\u0431\u0443\u043b\u044f\u0446\u0438\u0438 (\u043a\u0441\u0442\u0430\u0442\u0438, \u0442\u0443\u0442, \u043a\u0430\u043a \u0438 \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u0440\u043e\u0447\u0438\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430\u0445 \u043a\u0440\u043e\u043c\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439, \u043c\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c\u0441\u044f ASCII):<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">instance Statistic 'MaxLL (Tagged 'MaxLL) MaxLLState 'ByteOnly where   initState = MaxLLState 0 0   extractState MaxLLState { .. } = Tagged $ max maxLen curLen   computation = ByteOnlyComputation step     where       step MaxLLState { .. } 9 = MaxLLState maxLen $ curLen + 8 - (curLen `rem` 8)       step MaxLLState { .. } 8 = MaxLLState maxLen $ max 0 (curLen - 1)       step MaxLLState { .. } c | c == 10                               || c == 12                               || c == 13 = MaxLLState (max maxLen curLen) 0                                | c &lt; 32 = MaxLLState maxLen curLen       step MaxLLState { .. } _ = MaxLLState maxLen (curLen + 1)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u0430\u0436\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 backspace, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 <code>wc<\/code>!<\/p>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u0441\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c\u0443: \u0438\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e.<\/p>\n<p>  <\/p>\n<h2 id=\"kombinirovanie-statistik\">\u041a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a<\/h2>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 <code>a<\/code> \u2014 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430, \u0438 <code>b<\/code> \u2014 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430, \u0442\u043e \u0438\u0445 \u043f\u0430\u0440\u0430 \u2014 \u0442\u043e\u0436\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430, \u0438 \u044d\u0442\u043e \u043d\u0430\u0448 \u0448\u0430\u0433 \u0438\u043d\u0434\u0443\u043a\u0446\u0438\u0438. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0451\u043c \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0438\u043f\u0430 \u0434\u043b\u044f \u043f\u0430\u0440\u044b \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">infixr 5 ::: data a ::: b = a ::: b deriving (Show)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0442\u0438\u043f <code>(,)<\/code>, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u0441\u043c\u043e\u0436\u0435\u0442 \u043b\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043b\u0435\u043d\u0438\u0432\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 \u043d\u0435\u0442, \u0434\u0430 \u0438, \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u044d\u0442\u043e\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u043e\u0434\u043d\u044f\u0442\u044b\u0439 \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0442\u0438\u043f\u043e\u0432 \u043a\u043e\u0434 \u0431\u043e\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0440\u0430\u0437\u0438\u043c, \u043a\u0430\u043a \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0447\u0442\u043e \u043d\u0430\u0441\u0447\u0451\u0442 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0447\u0430\u043d\u043a\u043e\u0432\u044b\u0445 \u0438 \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a? \u0415\u0441\u043b\u0438 \u043e\u0431\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0447\u0430\u043d\u043a\u043e\u0432\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f, \u0442\u043e \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442, \u0438\u043d\u0430\u0447\u0435 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u044b\u043c \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u043e\u043c. \u041d\u0430 \u044f\u0437\u044b\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">type family CombineCompTy a b where   CombineCompTy 'Chunked 'Chunked = 'Chunked   CombineCompTy _ _ = 'ByteOnly<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Statistic<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0434\u043b\u044f \u043f\u0430\u0440\u044b \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a? \u041c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0442\u0430\u043a\u043e\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">instance (Statistic sa resa sta compa, Statistic sb resb stb compb)        =&gt; Statistic (sa '::: sb) (resa ::: resb) (sta ::: stb) (CombineCompTy compa compb) where   initState = initState ::: initState   extractState (a ::: b) = extractState a ::: extractState b   computation =     case (computation :: StatComputation sta compa, computation :: StatComputation stb compb) of          (ByteOnlyComputation a, ChunkedComputation b _)             -&gt; ByteOnlyComputation $ combine a b          (ChunkedComputation a _, ByteOnlyComputation b)             -&gt; ByteOnlyComputation $ combine a b          (ByteOnlyComputation a, ByteOnlyComputation b)              -&gt; ByteOnlyComputation $ combine a b          (ChunkedComputation stepA chunkA, ChunkedComputation stepB chunkB)             -&gt; ChunkedComputation (combine stepA stepB) (combine chunkA chunkB)     where       combine fa fb = \\(a ::: b) w -&gt; fa a w ::: fb b w<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c, \u0435\u0441\u043b\u0438 <code>sa<\/code> \u2014 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0441 \u0442\u0438\u043f\u043e\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 <code>resa<\/code>, \u0442\u0438\u043f\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f <code>sta<\/code> \u0438 \u0440\u0435\u0436\u0438\u043c\u043e\u043c \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 <code>compa<\/code>, \u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0434\u043b\u044f <code>sb<\/code>\/<code>resb<\/code>\/<code>stb<\/code>\/<code>compb<\/code>, \u0442\u043e \u043f\u0430\u0440\u0430 <code>sa ::: sb<\/code> \u2014 \u0442\u043e\u0436\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430, \u043f\u0440\u0438\u0447\u0451\u043c \u0435\u0451 \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u2014 \u043f\u0430\u0440\u0430 <code>resa ::: resb<\/code>, \u0442\u0438\u043f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u2014 \u043f\u0430\u0440\u0430 <code>sta ::: stb<\/code>, \u0430 \u0440\u0435\u0436\u0438\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <del>\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0442\u0438\u043f\u043e\u0432<\/del> <code>CombineCompTy compa compb<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435 \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 (\u0441 \u043a\u0440\u044b\u0436\u0435\u0447\u043a\u043e\u0439, \u0437\u0430\u043f\u0440\u043e\u043c\u043e\u0443\u0447\u0435\u043d\u043d\u044b\u043c) <code>:::<\/code>-\u0432-\u0440\u043e\u043b\u0438-\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0438 (\u0431\u0435\u0437 \u043a\u0440\u044b\u0436\u0435\u0447\u043a\u0438, \u043d\u0435\u0437\u0430\u043f\u0440\u043e\u043c\u043e\u0443\u0447\u0435\u043d\u043d\u044b\u043c) <code>:::<\/code>-\u0432-\u0440\u043e\u043b\u0438-\u0442\u0438\u043f\u0430 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430. <code>sa<\/code> \u0438 <code>sb<\/code> \u2014 <em>\u0442\u0435\u0440\u043c\u044b<\/em>, \u0437\u0430\u043f\u0440\u043e\u043c\u043e\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0442\u0438\u043f\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u044f\u0434\u043e\u043c \u0441 \u043d\u0438\u043c\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c (\u0437\u0430\u043f\u0440\u043e\u043c\u043e\u0443\u0447\u0435\u043d\u043d\u044b\u0439) \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 <em>\u0442\u0435\u0440\u043c\u043e\u0432<\/em>, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u2014 <em>\u0442\u0438\u043f\u044b<\/em>, \u0442\u0430\u043a \u0447\u0442\u043e \u0440\u044f\u0434\u043e\u043c \u0441 \u043d\u0438\u043c\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c (\u043d\u0435\u0437\u0430\u043f\u0440\u043e\u043c\u043e\u0443\u0447\u0435\u043d\u043d\u044b\u0439) \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 <em>\u0442\u0438\u043f\u043e\u0432<\/em>.<\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0451 \u0431\u044b \u0445\u043e\u0440\u043e\u0448\u043e, \u0432\u043e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e\u2026 \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0438\u043d\u0441\u0442\u0430\u043d\u0441. \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e \u0442\u0438\u043f\u043e\u0432 \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u044d\u0442\u043e \u043b\u0435\u0433\u043a\u043e \u043e\u0431\u043e\u0439\u0442\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u043e\u0432\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>comp<\/code> \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435\u043c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0440\u0430\u0432\u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u0430 \u0442\u0438\u043f\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">instance (Statistic sa resa sta compa,           Statistic sb resb stb compb,           comp ~ CombineCompTy compa compb)        =&gt; Statistic (sa '::: sb) (resa ::: resb) (sta ::: stb) comp where<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u0442\u0435\u0440\u043c\u044b. \u041f\u0435\u0440\u0432\u044b\u0435 \u0434\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u0440\u043e\u0441\u0442\u044b:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0430\u0440\u044b \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a \u0440\u0430\u0432\u043d\u043e \u043f\u0430\u0440\u0435 \u0438\u0437 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a.<\/li>\n<li>\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0438\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0430\u0440\u044b \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u044b \u0438\u0437 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f-\u043f\u0430\u0440\u044b \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 \u043d\u0438\u0445 \u043f\u0430\u0440\u0443.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u043d\u0430\u043c \u0442\u0443\u0442 \u043d\u0435 \u043d\u0443\u0436\u043d\u0430 \u043d\u0438 \u0435\u0434\u0438\u043d\u0430\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0442\u0438\u043f\u043e\u0432 \u2014 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0451 \u0441\u0430\u043c, \u0438 \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043a\u0440\u0443\u0442\u043e!<\/p>\n<p>  <\/p>\n<p>\u0422\u0440\u0435\u0442\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0443\u0436\u0435 \u043f\u043e\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u0438 \u043a\u0443\u0434\u0430 \u0431\u043e\u043b\u0435\u0435 \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u0435\u043d, \u043d\u043e \u043e\u043d \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0451\u0442\u0443 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c <code>CombineCompTy<\/code> (\u0438 \u0442\u0430\u0439\u043f\u0447\u0435\u043a\u0435\u0440 \u044d\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442). \u041e\u043f\u044f\u0442\u044c \u0436\u0435, \u0435\u0441\u043b\u0438 \u043e\u0431\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0447\u0430\u043d\u043a\u043e\u0432\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f, \u0442\u043e \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0430\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0438\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 (\u044d\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439), \u0430 \u0438\u043d\u0430\u0447\u0435 \u0432\u0441\u0451 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u043e\u043c\u0443 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044e.<\/p>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u043e\u0439\u043b\u0435\u0440\u043f\u043b\u0435\u0439\u0442\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u044f\u0432\u043d\u043e\u0433\u043e \u043f\u0430\u0442\u0442\u0435\u0440\u043d-\u043c\u0430\u0442\u0447\u0438\u043d\u0433\u0430 \u043f\u043e \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u043e\u043c\u0443 \u0438\u0437 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0442\u0430\u0439\u043f\u0447\u0435\u043a\u0435\u0440 \u043c\u043e\u0433 \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u0430\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0442\u043a\u0438 <code>case<\/code> \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f.<\/p>\n<p>  <\/p>\n<p>\u0410 \u043a\u0430\u043a\u043e\u0439 \u0442\u0438\u043f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439? \u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044e \u043a\u043b\u0430\u0441\u0441\u0430, \u044d\u0442\u043e <code>StatComputation st comp<\/code>, \u0433\u0434\u0435, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430, <code>comp ~ CombineCompTy compa compb<\/code>. \u0422\u043e \u0435\u0441\u0442\u044c, \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f <em>\u0437\u0430\u0432\u0438\u0441\u0438\u0442<\/em> \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 <code>compa<\/code> \u0438 <code>compb<\/code>. \u0410 \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c <code>CombineCompTy<\/code>, \u0442\u0430\u0439\u043f\u0447\u0435\u043a\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u043d\u0430\u0442\u044c, \u0440\u0430\u0432\u043d\u044b \u043b\u0438 <code>Chunked<\/code> \u0438 <code>compa<\/code>, \u0438 <code>compb<\/code>, \u0438\u043b\u0438 \u043d\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u041e\u0442\u043a\u0443\u0434\u0430 \u0442\u0430\u0439\u043f\u0447\u0435\u043a\u0435\u0440 \u0437\u043d\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>compa<\/code> \u0438\u043b\u0438 <code>compb<\/code>? \u0410 \u0432 \u043e\u0431\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d \u0438 \u043d\u0435 \u0437\u043d\u0430\u0435\u0442. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u0441\u043c\u0430\u0442\u0447\u0438\u043c\u0441\u044f \u043f\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e <code>computation<\/code>, \u0442\u043e \u0442\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0430 GADT. \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0449\u0451 \u0440\u0430\u0437 \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 <code>StatComputation<\/code>. \u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0431\u044b\u043b\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 <code>ChunkedComputation<\/code>, \u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f <code>comp<\/code> \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0440\u0430\u0432\u043d\u0430 <code>Chunked<\/code>. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 <code>ByteOnlyComputation<\/code>, \u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0432\u043d\u0430 <code>ByteOnly<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 <code>CombineCompTy<\/code> \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>_<\/code>-\u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u0432, \u0430 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u044f \u0432\u0441\u0435 \u0447\u0435\u0442\u044b\u0440\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438, \u0442\u043e \u0442\u0430\u0439\u043f\u0447\u0435\u043a\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u0431\u044b \u0437\u043d\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <em>\u0438<\/em> <code>compa<\/code>, <em>\u0438<\/em> <code>compb<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0415\u0449\u0451 \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u044b: <code>Words '::: Words<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0435, \u0441\u0447\u0438\u0442\u0430\u044e\u0449\u0435\u0439 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0432 \u0434\u0432\u0430\u0436\u0434\u044b. \u041f\u0443\u0440\u0438\u0441\u22a4\u044b \u043d\u0430 \u0442\u0430\u043a\u043e\u0435 \u0431\u044b \u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043d\u0435\u043e\u0434\u043e\u0431\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0446\u0435\u043b\u0435\u0439 \u043e\u043d\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0447\u0442\u043e \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u044d\u0442\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<h1 id=\"ispolzovanie-statistik\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a<\/h1>\n<p>  <\/p>\n<p>\u0421\u0443\u043f\u0435\u0440, \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043a\u0443\u0447\u0443 \u043a\u043e\u0434\u0430. \u041a\u0430\u043a \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c?<\/p>\n<p>  <\/p>\n<p>\u041f\u0443\u0441\u0442\u044c \u043d\u0430\u043c \u0434\u0430\u043d \u0442\u0438\u043f, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0441 <code>Statistic<\/code>, \u0438 <code>ByteString<\/code>, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0434\u043e \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443. \u0422\u043e\u0433\u0434\u0430 \u043c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c GADT, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>computation<\/code>. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e <code>ChunkedComputation<\/code>, \u0442\u043e \u043c\u044b \u0435\u043c\u0443 \u043a\u043e\u0440\u043c\u0438\u043c \u0432\u0441\u044e \u0432\u0445\u043e\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443. \u0418\u043d\u0430\u0447\u0435 \u044d\u0442\u043e <code>ByteOnlyComputation<\/code>, \u0438 \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c <code>BS.foldl'<\/code>. \u0418\u043b\u0438 \u0432 \u043a\u043e\u0434\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">wc :: forall s res st comp. Statistic s res st comp =&gt; BS.ByteString -&gt; res wc s = extractState $! runCompute computation   where     runCompute :: StatComputation st comp -&gt; st     runCompute (ByteOnlyComputation step) = BS.foldl' step initState s     runCompute (ChunkedComputation _ chunker) = chunker initState s<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u043d\u043e\u0432\u0430 \u043d\u0430\u0441 \u0432\u044b\u0440\u0443\u0447\u0430\u044e\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u0439\u043f\u0447\u0435\u043a\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043a\u043b\u0430\u0441\u0441\u0430 (<code>s<\/code>, <code>st<\/code>, <code>comp<\/code>) \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043b\u0438\u0448\u044c \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 <code>res<\/code>. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043f\u043e\u0445\u043e\u0436\u0435, \u0442\u0430\u0439\u043f\u0447\u0435\u043a\u0435\u0440 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0442\u0438\u043f <code>runCompute<\/code>, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u044f\u0432\u043d\u043e. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 <code>st<\/code> \u0438 <code>comp<\/code> \u0432 \u0435\u0451 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0432 \u0442\u0438\u043f\u0435 <code>wc<\/code>, \u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e (<em>\u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e<\/em>) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>forall<\/code> \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 <code>ScopedTypeVariables<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043b\u0438\u0431\u043e \u0447\u0435\u0440\u0435\u0437 \u044f\u0432\u043d\u0443\u044e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e \u0442\u0438\u043f\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">let result = wc someBS :: Tagged 'Words ::: Tagged 'Lines<\/code><\/pre>\n<p>  <\/p>\n<p>\u043b\u0438\u0431\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f <code>TypeApplications<\/code> \u0438 \u044f\u0432\u043d\u043e\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>s<\/code> \u0432 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">let result = wc @('Words '::: 'Lines) someBS<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b, \u043d\u043e, \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0447\u0443\u0442\u044c \u043b\u0443\u0447\u0448\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u0441\u043c\u044b\u0441\u043b \u043a\u043e\u0434\u0430 \u0431\u043e\u043b\u0435\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<p>  <\/p>\n<h2 id=\"predvaritelnaya-ocenka-proizvoditelnosti\">\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0446\u0435\u043d\u043a\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/h2>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0430\u0432\u0434\u0430\u043d\u044b \u043b\u0438 \u043d\u0430\u0448\u0438 \u0443\u0441\u0438\u043b\u0438\u044f, \u0438\u043b\u0438 \u0436\u0435 \u043c\u044b \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u044c \u0432\u0441\u0435\u0439 \u044d\u0442\u043e\u0439 \u0435\u0440\u0443\u043d\u0434\u043e\u0439 \u0432\u043f\u0443\u0441\u0442\u0443\u044e?<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0437\u043c\u0435\u0440\u0438\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 <code>wc @'Words<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0441\u044e \u0442\u0443 \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u044e. \u041d\u0430\u0438\u043b\u0443\u0447\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u2014 1.51 \u0441\u0435\u043a\u0443\u043d\u0434, \u043d\u0435\u043c\u043d\u043e\u0433\u0438\u043c \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043e\u0434\u043d\u0438\u0445 \u043b\u0438\u0448\u044c \u0431\u0430\u0439\u0442, \u0441\u043b\u043e\u0432 \u0438 \u0441\u0442\u0440\u043e\u043a \u0432 \u043d\u0435\u043c\u043e\u0434\u0443\u043b\u044f\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438. \u041d\u0435 \u0444\u043e\u043d\u0442\u0430\u043d, \u043d\u043e \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u043f\u043b\u043e\u0445\u043e.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0440\u043e\u0448 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432 \u0443\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0437\u043c\u0435\u0440\u0438\u043c <code>wc @('Words '::: 'Words)<\/code>!<\/p>\n<p>  <\/p>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0442 \u043b\u0438\u0447\u043d\u043e \u0443 \u043c\u0435\u043d\u044f \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u0430\u044f \u0435\u0440\u0443\u043d\u0434\u0430. \u042f \u0431\u044b \u043e\u0436\u0438\u0434\u0430\u043b, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0446\u0438\u0444\u0440\u044b, \u0432 \u0438\u0434\u0435\u0430\u043b\u0435 \u2014 \u0442\u0430\u043a\u0438\u0435 \u0436\u0435, \u043d\u043e\u2026 \u041e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 <em>\u0431\u044b\u0441\u0442\u0440\u0435\u0435<\/em>: 1.34 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u0410 \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c <code>wc @('Words '::: 'Words '::: 'Words)<\/code>? 1.30 \u0441\u0435\u043a\u0443\u043d\u0434. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <code>'Words<\/code> \u043d\u0435 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0440\u0430\u043d\u043d\u043e \u2014 \u044d\u0442\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043d\u0435\u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u044b \u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u043b\u044e\u0434\u0435\u0439. \u042f \u043f\u043e\u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u043b \u043d\u0430\u0440\u043e\u0434 \u0432 \u0438\u0440\u043a\u0435 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0435 <code>#haskell<\/code> \u2014 \u0443 \u043d\u0438\u0445 \u044d\u0442\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043b\u0441\u044f. \u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0431\u044b\u043b\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u043c \u0438 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u044f\u0449\u0438\u043c \u043e\u0442 \u0447\u0438\u0441\u043b\u0430 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0432 \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0423 \u043c\u0435\u043d\u044f \u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0442 \u0445\u043e\u0440\u043e\u0448\u0435\u0433\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f. \u042f \u043f\u043e\u043c\u0435\u0434\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430 GHC Core \u2014 \u0431\u0435\u0437\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043d\u043e, \u0432\u0441\u0451 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0440\u0430\u0437\u0443\u043c\u043d\u044b\u043c. \u0415\u0441\u043b\u0438 \u0431\u044b \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u043e\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0435, \u044f \u0431\u044b \u043c\u043e\u0433 \u043f\u043e\u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u0438\u043d\u043b\u0430\u0439\u043d\u0435\u0440\u0430, \u0438\u043b\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430, \u0438\u043b\u0438 \u043e \u0447\u0451\u043c-\u0442\u043e \u0442\u0430\u043a\u043e\u043c. \u041d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u044d\u0442\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043d\u0435 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u043b\u044e\u0434\u0435\u0439\u2026 \u0421\u0442\u0440\u0430\u043d\u043d\u043e\u0442\u0430-\u0435\u0440\u0443\u043d\u0434\u0430. \u042f \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u043f\u043e\u0447\u0435\u043c\u0443 \u043a\u043e\u0434 \u0442\u0430\u043a \u0441\u0435\u0431\u044f \u0432\u0435\u0434\u0451\u0442, \u0438 \u043d\u0435 \u043c\u043e\u0433\u0443 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u043d\u0435 \u044d\u0442\u043e \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u041b\u0430\u0434\u043d\u043e, \u0445\u0432\u0430\u0442\u0438\u0442 \u043d\u044b\u0442\u044c, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0449\u0451 \u043f\u043e\u0438\u0437\u043c\u0435\u0440\u044f\u0435\u043c. \u0427\u0442\u043e \u043d\u0430\u0441\u0447\u0451\u0442 \u0432\u0441\u0435\u0445 \u0442\u0440\u0451\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435? \u0418\u0437\u043c\u0435\u0440\u0438\u043c <code>wc @('Bytes '::: 'Words '::: 'Lines)<\/code>! \u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 1.53 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u042d\u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u0438\u043c \u0445\u0443\u0436\u0435 1.45 \u0441\u0435\u043a\u0443\u043d\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435, \u043d\u043e, \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0432\u043f\u043e\u043b\u043d\u0435 \u0442\u0435\u0440\u043f\u0438\u043c\u043e.<\/p>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u044d\u043c\u043f\u0438\u0440\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u043a\u0430\u0437\u0430\u043b\u0438, \u0447\u0442\u043e \u0443 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0445\u043e\u0442\u044f \u0431\u044b \u0435\u0441\u0442\u044c \u0448\u0430\u043d\u0441. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u0438\u0435 \u043f\u043b\u043e\u0434\u044b \u043d\u0430\u043c \u0434\u0430\u0451\u0442 \u0442\u0430\u043a\u0430\u044f \u043c\u043e\u0434\u0443\u043b\u044f\u0440\u0438\u0437\u0430\u0446\u0438\u044f.<\/p>\n<p>  <\/p>\n<h1 id=\"testirovanie\">\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<p>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u2014 \u043e\u0434\u043d\u043e \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435! \u041b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0434\u0430\u0451\u0442 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u043e\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0432 \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0432 \u0440\u0430\u0432\u043d\u043e \u0434\u043b\u0438\u043d\u0435 \u0441\u043f\u0438\u0441\u043a\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>words<\/code>, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0441 \u043a\u043e\u0434\u043e\u043c \u0432\u044b\u0448\u0435 <code>127<\/code>. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u044d\u0442\u043e <em>\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c<\/em> \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0441\u043b\u043e\u0432, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u043e\u043f\u0440\u043e\u0441 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u0441\u043a\u0438\u0445 \u0432\u0437\u0433\u043b\u044f\u0434\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u044d\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043d\u0430\u0431\u043e\u0440 QuickCheck-\u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0438 \u0434\u043b\u044f ASCII, \u0438 \u0434\u043b\u044f UTF-8-\u0432\u0445\u043e\u0434\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">import qualified Data.ByteString.Char8 as BS import qualified Data.Text as T import qualified Data.Text.Encoding as T -- \u0435\u0449\u0451 \u0441\u043a\u0443\u0447\u043d\u044b\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b  import Data.WordCount  wrapUnicode :: UnicodeString -&gt; (BS.ByteString, T.Text) wrapUnicode ustr = (T.encodeUtf8 txt, txt)   where     txt = T.pack $ getUnicodeString ustr  replaceNonAsciiSpaces :: Char -&gt; Char replaceNonAsciiSpaces ch | ch &gt;= chr 127 &amp;&amp; isSpace ch = '_'                          | otherwise = ch  main :: IO () main = hspec $ parallel $ modifyMaxSuccess (const 10000) $ modifyMaxSize (const 1000) $ do   describe &quot;ASCII support&quot; $ do     it &quot;Counts bytes correctly&quot; $ property $       \\(getASCIIString -&gt; str) -&gt; wc @'Bytes (BS.pack str) `shouldBe` genericLength str     it &quot;Counts chars correctly&quot; $ property $       \\(getASCIIString -&gt; str) -&gt; wc @'Chars (BS.pack str) `shouldBe` genericLength str     it &quot;Counts words correctly&quot; $ property $       \\(getASCIIString -&gt; str) -&gt; wc @'Words (BS.pack str) `shouldBe` genericLength (words str)     it &quot;Counts lines correctly&quot; $ property $       \\(getASCIIString -&gt; str) -&gt; wc @'Lines (BS.pack str) `shouldBe` genericLength (filter (== '\\n') str)   describe &quot;UTF8 support&quot; $ do     it &quot;Counts bytes correctly&quot; $ property $       \\(wrapUnicode -&gt; (bs, _))   -&gt; wc @'Bytes bs `shouldBe` fromIntegral (BS.length bs)     it &quot;Counts chars correctly&quot; $ property $       \\(wrapUnicode -&gt; (bs, txt)) -&gt; wc @'Chars bs `shouldBe` fromIntegral (T.length txt)     it &quot;Counts words correctly&quot; $ property $       \\(wrapUnicode -&gt; (bs, txt)) -&gt; wc @'Words bs `shouldBe` genericLength (T.words $ T.map replaceNonAsciiSpaces txt)     it &quot;Counts lines correctly&quot; $ property $       \\(wrapUnicode -&gt; (bs, txt)) -&gt; wc @'Lines bs `shouldBe` fromIntegral (T.count &quot;\\n&quot; txt)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418 \u0432\u0441\u0451!<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043c\u0435\u0442\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0449\u0435\u0439:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0412 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u0430\u043a \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0435 \u0442\u0435\u043e\u0440\u0435\u043c\u044b \u0438 \u0432\u043f\u043e\u043b\u043d\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0438\u0445 \u0434\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u044f\u0437\u044b\u043a\u0430, \u0447\u0442\u043e \u0434\u0430\u0451\u0442 \u043a\u0443\u0434\u0430 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0432 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438, \u0447\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u044b\u0441\u044f\u0447 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432. \u0412 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043a\u043e\u0435-\u043a\u0430\u043a\u043e\u0439 \u0431\u0430\u0433 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 UTF-8-\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043b\u043e\u0432\u0438\u043b\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0432\u0445\u043e\u0434\u0435 \u0438\u0437 \u0432\u0442\u043e\u0440\u043e\u0439 \u0438\u043b\u0438 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0442\u044b\u0441\u044f\u0447\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432.<\/li>\n<li>\u041c\u044b \u043d\u0435 \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u043c \u0438 \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0438\u043a\u0430\u043a\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0434\u043b\u0438\u043d\u044b \u0441\u0442\u0440\u043e\u043a, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e\u2026 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e.<\/li>\n<li>\u0422\u0435\u0441\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e: \u043f\u0440\u043e\u0433\u043d\u0430\u0442\u044c \u0438\u0445 \u0432\u0441\u0435 \u043d\u0430 10 \u0442\u044b\u0441\u044f\u0447\u0430\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 (\u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430) \u0434\u043b\u0438\u043d\u043e\u0439 \u0434\u043e \u0442\u044b\u0441\u044f\u0447\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 3-5 \u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0430 \u043c\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 (\u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445).<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044e \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u0434\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0430 C \u0438\u0437 GNU Coreutils.<\/p>\n<p>  <\/p>\n<h1 id=\"obrabotka-opciy-komandnoy-stroki\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u043f\u0446\u0438\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438<\/h1>\n<p>  <\/p>\n<p>\u0412\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 <a href=\"https:\/\/hackage.haskell.org\/package\/optparse-applicative\" rel=\"nofollow\">optparse-applicative<\/a>. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0442\u0438\u043f, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439 \u043e\u043f\u0446\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, \u0438 \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u043d\u0435\u0433\u043e:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">data Options = Options   { countBytes :: Bool   , countChars :: Bool   , countLines :: Bool   , countMaxLineLength :: Bool   , countWords :: Bool   , files :: [FilePath]   }  options :: Parser Options options = Options   &lt;$&gt; switch (long &quot;bytes&quot; &lt;&gt; short 'c' &lt;&gt; help &quot;print the byte counts&quot;)   &lt;*&gt; switch (long &quot;chars&quot; &lt;&gt; short 'm' &lt;&gt; help &quot;print the character counts&quot;)   &lt;*&gt; switch (long &quot;lines&quot; &lt;&gt; short 'l' &lt;&gt; help &quot;print the newline counts&quot;)   &lt;*&gt; switch (long &quot;max-line-length&quot; &lt;&gt; short 'L' &lt;&gt; help &quot;print the maximum display width&quot;)   &lt;*&gt; switch (long &quot;words&quot; &lt;&gt; short 'w' &lt;&gt; help &quot;print the word counts&quot;)   &lt;*&gt; some (argument str (metavar &quot;FILES...&quot;))<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448 <code>main<\/code>, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u043e\u043f\u0446\u0438\u0438 \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 <code>Statistics<\/code>, \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0431\u0430\u0439\u0442\u044b, \u0441\u043b\u043e\u0432\u0430 \u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">main :: IO () main = do   Options { .. } &lt;- execParser $ info (options &lt;**&gt; helper) (fullDesc &lt;&gt; progDesc &quot;Print newline, word, and byte counts for each file&quot;)   let selectedStats = map snd $ filter fst [ (countBytes, Bytes), (countChars, Chars)                                            , (countWords, Words), (countMaxLineLength, MaxLL)                                            , (countLines, Lines)                                            ]   let stats | null selectedStats = [Bytes, Words, Lines]             | otherwise = selectedStats<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u0441\u0451 \u044d\u0442\u043e \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0449\u0451 \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u0435\u0435, \u043d\u043e \u0446\u0435\u043b\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0435 \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430\u043c \u0431\u044b \u0443\u0436 \u0445\u043e\u0442\u044c \u043a\u0430\u043a-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u043f\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u043f\u0446\u0438\u0439 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438. \u0427\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435? \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0432 <em>\u0442\u0438\u043f<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043a\u043e\u0440\u043c\u0438\u0442\u044c <code>wc<\/code>. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0435\u0440\u043c, \u0438 \u043d\u0430\u043c \u0438\u0437 \u043d\u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0438\u043f. \u0417\u0432\u0443\u0447\u0438\u0442 \u043f\u0440\u044f\u043c\u043e \u043a\u0430\u043a \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0442\u0438\u043f\u044b!<\/p>\n<p>  <\/p>\n<h2 id=\"pochti-zavisimye-tipy\">\u041f\u043e\u0447\u0442\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0442\u0438\u043f\u044b<\/h2>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043e\u0431\u0440\u0435\u0447\u0451\u043d \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u044b \u043f\u043e\u0437\u0434\u043d\u0435\u0435, \u043d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0435\u0433\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c, \u0432\u0435\u0434\u044c \u0442\u0430\u043a \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043e\u043a\u043e\u043b\u043e\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0432 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c \u0445\u0430\u0441\u043a\u0435\u043b\u0435, \u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0442\u0438\u043f\u044b \u2014 \u044d\u0442\u043e \u043a\u0440\u0443\u0442\u043e!<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u043c\u0438 \u0448\u0430\u0436\u043e\u0447\u043a\u0430\u043c\u0438 \u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <a href=\"https:\/\/hackage.haskell.org\/package\/singletons\" rel=\"nofollow\">\u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u043e\u0432<\/a>, \u0447\u0442\u043e\u0431\u044b \u043b\u0443\u0447\u0448\u0435 \u043f\u0440\u043e\u0447\u0443\u0432\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0442\u0438\u043f\u043e\u0432 \u0438 \u043a\u0430\u043a\u0438\u0435 \u0443 \u043d\u0435\u0451 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0437\u0430\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 \u044d\u043a\u0437\u0438\u0441\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">data SomeStats where   MkSomeStats :: Statistic s res st comp =&gt; proxy s -&gt; SomeStats<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c <code>proxy s<\/code> \u2014 \u0441\u0432\u0438\u0434\u0435\u0442\u0435\u043b\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 <code>Statistic<\/code>. \u0415\u0433\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043d\u0430\u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u0442\u0438\u043f\u043e\u043c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u041f\u0443\u0441\u0442\u044c \u0442\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u044d\u043a\u0437\u0438\u0441\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u041a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f? \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0442\u0430\u043a\u043e\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">wc' :: SomeStats -&gt; BS.ByteString -&gt; ? wc' (MkSomeStats (_ :: proxy s)) input = wc @s input<\/code><\/pre>\n<p>  <\/p>\n<p>\u043d\u043e\u2026 \u0427\u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e <code>?<\/code>? \u041a\u0430\u043a\u043e\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438? \u041f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u044d\u0442\u043e <code>res<\/code> \u0438\u0437 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 <code>Statistic<\/code>, \u043d\u043e \u0443 \u043d\u0430\u0441 \u0435\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u0435\u0442, \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a?<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">data SomeStats where   MkSomeStats :: Statistic s res st comp =&gt; proxy1 s -&gt; proxy2 res -&gt; SomeStats  wc' :: SomeStats -&gt; BS.ByteString -&gt; res wc' (MkSomeStats (_ :: proxy1 s) (_ :: proxy2 res)) input = wc @s input<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442: \u0432 \u0442\u043e\u0447\u043a\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 <code>wc'<\/code> \u043d\u0430\u043c \u0435\u0449\u0451 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 <code>res<\/code>, \u0437\u0430\u0432\u0451\u0440\u043d\u0443\u0442\u044b\u0439 \u0432\u043d\u0443\u0442\u0440\u044c <code>SomeStats<\/code>, \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0436\u0435 \u0434\u0435\u043b\u0430\u0442\u044c?<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0448\u0430\u0433 \u043d\u0430\u0437\u0430\u0434 \u0438 \u043f\u043e\u0434\u0443\u043c\u0430\u0435\u043c. \u041c\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f <code>wc<\/code>, \u043d\u043e \u043d\u0430\u043c \u044d\u0442\u043e \u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e! \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e. \u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043d\u0430\u043c \u0432\u0430\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>show<\/code>, \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0441\u0442\u0440\u0435\u0439\u043d\u0442, \u0447\u0442\u043e <code>res<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Show<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">data SomeStats where   MkSomeStats :: (Statistic s res st comp, Show res) =&gt; proxy s -&gt; SomeStats<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e\u0433\u0434\u0430 <code>wc<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">wc' :: SomeStats -&gt; BS.ByteString -&gt; String wc' (MkSomeStats (_ :: proxy s)) input = show $ wc @s input<\/code><\/pre>\n<p>  <\/p>\n<p>\u0438 \u044d\u0442\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u043d\u043e \u043a\u0430\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0441\u043f\u0438\u0441\u043e\u043a <code>stats<\/code> \u0432 <code>SomeStats<\/code>? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0451\u043c \u0441 \u043f\u0440\u043e\u043c\u043e\u0443\u0442\u0438\u043d\u0433\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">promoteStat :: Statistics -&gt; SomeStats promoteStat Bytes = MkSomeStats (Proxy :: Proxy 'Bytes) promoteStat Chars = MkSomeStats (Proxy :: Proxy 'Chars) promoteStat Words = MkSomeStats (Proxy :: Proxy 'Words) promoteStat MaxLL = MkSomeStats (Proxy :: Proxy 'MaxLL) promoteStat Lines = MkSomeStats (Proxy :: Proxy 'Lines)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0443\u0440\u043e\u0434\u043b\u0438\u0432\u043e, \u0434\u0430 \u0438 \u0433\u0440\u0443\u0441\u0442\u043d\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 <code>Statistics<\/code>, \u043d\u043e \u0442\u0430\u043a\u043e\u0432\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0442\u0438\u043f\u043e\u0432 \u0445\u0430\u0441\u043a\u0435\u043b\u044f. \u0412\u043e\u0442 \u0442\u0435\u0431\u0435 \u0438 \u044d\u0440\u0437\u0430\u0446-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0442\u0438\u043f\u044b: \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e <em>\u0442\u0435\u0440\u043c<\/em> <code>Bytes<\/code> \u0438 (\u0437\u0430\u043f\u0440\u043e\u043c\u043e\u0443\u0447\u0435\u043d\u043d\u044b\u0439) <em>\u0442\u0438\u043f<\/em> <code>'Bytes<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e, \u0442\u0430\u0439\u043f\u0447\u0435\u043a\u0435\u0440 \u0438\u0445 \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0431\u0435\u0437 \u0432\u0441\u044f\u043a\u043e\u0439 \u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438, \u0438 \u043d\u0430\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0432\u044f\u0437\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0441 \u044d\u0442\u0438\u043c \u043d\u0430\u0448\u0438\u043c <code>promoteStat<\/code> \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u0438 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u0441\u043f\u0438\u0441\u043a\u0443 \u0446\u0435\u043b\u0438\u043a\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">promoteStats :: [Statistics] -&gt; SomeStats promoteStats [s] = promoteStat s promoteStats (s:ss) =   case (promoteStat s, promoteStats ss) of        (MkSomeStats (_ :: proxy1 st), MkSomeStats (_ :: proxy2 sst))                                    -&gt; MkSomeStats (Proxy :: Proxy (st '::: sst))<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u0430, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0433\u043e \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>promoteStat<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0436\u0435 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0438 \u0431\u043e\u043b\u0435\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u043e \u0432\u0441\u0451 \u043a\u0443\u0434\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u0441\u0451 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e \u0434\u043b\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439: \u0433\u043e\u043b\u043e\u0432\u0443 \u043c\u044b \u043f\u0440\u043e\u043c\u043e\u0443\u0442\u0438\u043c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0442\u043e\u0433\u043e \u0436\u0435 <code>promoteStat<\/code>, \u0430 \u0445\u0432\u043e\u0441\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u043c <code>promoteStats<\/code>. \u0414\u0430\u043b\u044c\u0448\u0435 \u0438\u0445 \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u0442\u044c, \u0438 \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043b\u0451\u0433\u043a\u0430\u044f \u043c\u0430\u0433\u0438\u044f. \u041c\u044b \u043c\u0430\u0442\u0447\u0438\u043c\u0441\u044f \u043f\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u0432 <code>promoteStat<\/code> \u0438 <code>promoteStats<\/code>, \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <em>\u0442\u0438\u043f\u0430<\/em> <code>st<\/code> \u043a \u0442\u0438\u043f\u0443, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u0433\u043e\u043b\u043e\u0432\u0435 \u0441\u043f\u0438\u0441\u043a\u0430, \u0430 <code>sst<\/code> \u2014 \u043a \u0442\u0438\u043f\u0443, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u0445\u0432\u043e\u0441\u0442\u0443.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u043c \u043e\u0431 \u044d\u0442\u0438\u0445 \u0442\u0438\u043f\u0430\u0445 \u043a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u043a\u043b\u0430\u0441\u0441 <code>Statistic<\/code> (\u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0435\u0439\u043d\u0442\u043e\u043c \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u044d\u043a\u0437\u0438\u0441\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430). \u041d\u043e \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 <code>Statistic<\/code>, \u0442\u043e \u0438 <code>st ::: sst<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Statistic<\/code> \u043a\u0430\u043a \u0440\u0430\u0437 \u0438\u0437-\u0437\u0430 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0432\u044b\u0448\u0435! \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e <code>rest<\/code> \u0438 <code>resst<\/code> (\u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u044b\u0435 \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u043e\u0432, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a <code>st<\/code> \u0438 <code>sst<\/code>) \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 <code>Show<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438, \u0447\u0442\u043e <code>rest ::: resst<\/code> \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>Show<\/code>, \u0430 \u044d\u0442\u043e \u0440\u043e\u0432\u043d\u044b\u043c \u0441\u0447\u0451\u0442\u043e\u043c \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 <code>st ::: sst<\/code>!<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0440\u043e\u0447\u0435, \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <code>MkSomeStats (Proxy :: Proxy (st '::: sst))<\/code> \u0432\u043f\u043e\u043b\u043d\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043e. \u0418 \u043e\u0447\u0435\u043d\u044c \u043a\u0440\u0443\u0442\u043e, \u0447\u0442\u043e \u0442\u0430\u0439\u043f\u0447\u0435\u043a\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u044d\u0442\u043e \u0432\u0441\u0451 \u0441\u0430\u043c \u0432\u044b\u0432\u0435\u0441\u0442\u0438!<\/p>\n<p>  <\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u044d\u0442\u043e \u043d\u0435 \u0442\u043e\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f: \u043c\u044b \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u0443\u0441\u0442\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430 \u043e\u043f\u0446\u0438\u0439. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043e\u043d \u0443 \u043d\u0430\u0441 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0438 \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442, \u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0435\u0449\u0435\u0439 \u0432\u0440\u043e\u0434\u0435 <code>NonEmpty<\/code> \u0443\u0441\u043b\u043e\u0436\u043d\u0438\u0442 \u0438\u0437\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0435\u0437 \u0432\u0441\u044f\u043a\u043e\u0439 \u0432\u0438\u0434\u0438\u043c\u043e\u0439 \u0432\u044b\u0433\u043e\u0434\u044b.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0431\u044b \u0442\u0430\u043c \u043d\u0438 \u0431\u044b\u043b\u043e, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u043b\u0435\u0433\u043a\u043e:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">main :: IO () main = do   -- obtaining `stats` as before   forM_ files $ \\path -&gt; do     contents &lt;- unsafeMMapFile path     putStrLn $ wc' (promoteStats stats) contents<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"chudesa-proizvoditelnosti\">\u0427\u0443\u0434\u0435\u0441\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/h3>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e (\u043d\u0435)\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u0435\u043d \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434?<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a\u0438, \u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043c\u043d\u043e\u0433\u043e\u043e\u0431\u0435\u0449\u0430\u044e\u0449\u0438\u0435 1.05 \u0441\u0435\u043a\u0443\u043d\u0434 \u2014 \u0440\u043e\u0432\u043d\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0435, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 <code>BS.count 10<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u044d\u0442\u043e \u0447\u0430\u043d\u043a\u043e\u0432\u0430\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0432\u0435\u0441\u044c \u0432\u0445\u043e\u0434 \u0437\u0430 \u0440\u0430\u0437. \u041a\u0430\u043a \u043d\u0430\u0441\u0447\u0451\u0442 \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0438\u0441\u043b\u0430 \u0441\u043b\u043e\u0432? \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u043c, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u2026 14 \u0441\u0435\u043a\u0443\u043d\u0434 \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u043e\u043b\u0443\u0442\u043e\u0440\u0430.<\/p>\n<p>  <\/p>\n<p>\u0427\u0451\u0440\u0442, <strong>14 \u0441\u0435\u043a\u0443\u043d\u0434<\/strong>.<\/p>\n<p>  <\/p>\n<p>\u0418, \u043a\u0441\u0442\u0430\u0442\u0438, \u043e\u043d\u043e \u0436\u0443\u0451\u0442 \u043f\u0430\u043c\u044f\u0442\u044c \u043a\u0430\u043a \u0431\u0435\u0448\u0435\u043d\u043e\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">  74,873,139,008 bytes allocated in the heap<\/code><\/pre>\n<p>  <\/p>\n<p>\u042f \u043d\u0435 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u043c\u0435\u0440\u043e\u0432 \u0430\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u0439 \u0434\u043b\u044f \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439, \u043d\u043e \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u043b\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u0430. \u041d\u0443, \u0445\u043e\u0442\u044f \u0431\u044b \u044d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0432\u0441\u0451 \u0435\u0449\u0451 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/655\/b80\/5d6\/655b805d68b4b00a4e90f64eefbc6f1c.svg\" alt=\"$O(1)$\" data-tex=\"inline\"><\/math> \u043f\u043e \u043f\u0430\u043c\u044f\u0442\u0438 \u2014 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0430\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u0439 \u043f\u043e\u0447\u0442\u0438 \u0441\u0440\u0430\u0437\u0443 \u0443\u043c\u0438\u0440\u0430\u044e\u0442 \u0432 \u043d\u0443\u043b\u0435\u0432\u043e\u043c \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u0438 GC (<code>60,512 bytes maximum residency<\/code>).<\/p>\n<p>  <\/p>\n<p>\u041b\u0430\u0434\u043d\u043e. \u0427\u0442\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0438 \u0441\u043b\u043e\u0432\u0430, \u0438 \u0441\u0442\u0440\u043e\u043a\u0438? <strong>27 \u0441\u0435\u043a\u0443\u043d\u0434<\/strong>, 120 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442 \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u043d\u0430\u0441\u0447\u0451\u0442 \u0441\u043b\u043e\u0432, \u0441\u0442\u0440\u043e\u043a \u0438 \u0431\u0430\u0439\u0442? \u041c\u043e\u0436\u0435\u0442\u0435 \u0443\u0433\u0430\u0434\u0430\u0442\u044c?<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u043a\u0430\u0437\u0430\u043b\u0438 \u00ab42 \u0441\u0435\u043a\u0443\u043d\u0434\u044b\u00bb, \u0442\u043e \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u044a\u0435\u0441\u0442\u044c \u043f\u0438\u0440\u043e\u0436\u043e\u043a: \u043e\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f 41 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u0438 \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u0443\u0435\u0442 194 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442\u0430. \u041d\u0443, <em>\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435<\/em> \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e RTS \u0445\u043e\u0442\u044f \u0431\u044b \u0432\u0441\u0451 \u0435\u0449\u0451 \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 60 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u0432\u0441\u0451 \u0442\u0430\u043a \u043f\u043b\u043e\u0445\u043e?<\/p>\n<p>  <\/p>\n<p>\u041d\u0443, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u0442\u0430\u043a\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">wc' (MkSomeStats (_ :: proxy s)) input = show $ wc @s input<\/code><\/pre>\n<p>  <\/p>\n<p>\u0442\u043e\u0433\u0434\u0430 <em>\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440<\/em> \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 <code>computation<\/code> \u0441\u0432\u044f\u0437\u0430\u043d \u0441 \u0434\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 <code>s<\/code> \u2014 \u044d\u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u043d\u0442\u0430\u0439\u043c-\u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u0432\u044b\u0431\u043e\u0440. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043d\u0435\u0442 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u0430, \u043a\u0440\u043e\u043c\u0435 \u043a\u0430\u043a \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0432 \u043f\u0440\u044f\u043c\u0443\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0441\u043b\u043e\u0432\u0430\u0440\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Statistic<\/code> \u0438 \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430\u0440\u044f \u043f\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044e \u0431\u0435\u0437 \u043a\u0430\u043a\u043e\u0433\u043e \u0431\u044b \u0442\u043e \u043d\u0438 \u0431\u044b\u043b\u043e \u0438\u043d\u043b\u0430\u0439\u043d\u0438\u043d\u0433\u0430.<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442?<\/p>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>wc'<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>computation<\/code>, \u043e\u0431\u0451\u0440\u043d\u0443\u0442\u044b\u0439 \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u043a\u0437\u0438\u0441\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 <code>SomeStats<\/code> \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u044d\u0442\u043e\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0434\u0430\u043b\u044c\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>wc<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044e <em>\u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0431\u0430\u0439\u0442\u0430<\/em>. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u0438\u043d\u043b\u0430\u0439\u043d\u0438\u043d\u0433\u0430, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u044d\u0442\u0438\u043c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0439, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0433\u043e\u0440\u044f\u0447\u0438\u0445 \u0446\u0438\u043a\u043b\u043e\u0432, \u0430 \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0435\u0433\u043e \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u0422\u043e \u0435\u0441\u0442\u044c, \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 1.8 \u043c\u0438\u043b\u043b\u0438\u0430\u0440\u0434\u043e\u0432 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u2014 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e!<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u0430 \u0437\u0430 \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0443 \u0432\u0441\u0435\u0445 \u043d\u0443\u0436\u043d\u044b\u0445 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u044d\u043a\u0437\u0438\u0441\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>promoteStats<\/code>. \u041a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0430 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442?<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 <code>stats<\/code> \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">promoteStats [s] = promoteStat s<\/code><\/pre>\n<p>  <\/p>\n<p>\u0438 \u0435\u0441\u043b\u0438 <code>s<\/code> \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>Words<\/code>, \u0442\u043e <code>promoteStat<\/code> \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">promoteStat Words = MkSomeStats (Proxy :: Proxy 'Words)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 <code>promoteStats<\/code> \u0437\u0430\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0432 <code>SomeStats<\/code> \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u044b, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Statistic<\/code> \u0434\u043b\u044f <code>Words<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439. \u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u0435\u0441\u043b\u0438 \u0432 \u0434\u0435\u043b\u043e \u0432\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0432\u0442\u043e\u0440\u043e\u0435 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435?<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">promoteStats (s:ss) =   case (promoteStat s, promoteStats ss) of          (MkSomeStats (_ :: proxy1 st), MkSomeStats (_ :: proxy2 sst)) -&gt; MkSomeStats (Proxy :: Proxy (st '::: sst))<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0444\u0443\u043a\u043d\u0446\u0438\u044e <code>computation<\/code> \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: <code>case<\/code> \u0432 \u043f\u0440\u0430\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0438\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0432\u0435\u0440\u043d\u0443\u043b\u0438 <code>promoteStat<\/code> \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 <code>promoteStats<\/code>, \u0438, \u0435\u0441\u043b\u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u0442\u044c, \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>computation<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>Statistic<\/code> \u0434\u043b\u044f \u00ab\u0438\u043d\u0434\u0443\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e\u00bb \u0441\u043b\u0443\u0447\u0430\u044f <code>sa ::: sb<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e \u044d\u0442\u0438\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c \u043e\u0434\u0438\u043d \u0437\u0430 \u0434\u0440\u0443\u0433\u0438\u043c.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u043f\u0446\u0438\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u043c\u044b \u043f\u043b\u0430\u0442\u0438\u043c \u043e\u0432\u0435\u0440\u0445\u0435\u0434 \u0432 13-14 \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u0432\u0430\u0436\u0434\u044b, \u0438 \u043e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 28 \u0441\u0435\u043a\u0443\u043d\u0434 \u2014 \u0440\u043e\u0432\u043d\u043e \u043a\u0430\u043a \u043c\u044b \u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u043b\u0438. \u0410 \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0432\u0441\u0435 \u043f\u044f\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0431\u044b\u043b\u043e \u0431\u044b 65-70 \u0441\u0435\u043a\u0443\u043d\u0434.<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u044d\u043a\u0437\u0438\u0441\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b (\u0434\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0441\u0442\u0438\u0440\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432) \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u0440\u0435\u043d\u043e\u0432\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430.<\/p>\n<p>  <\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u043c\u044b \u0437\u0430\u043e\u0434\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041e\u0432\u0435\u0440\u0445\u0435\u0434 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 13 \u0441\u0435\u043a\u0443\u043d\u0434 (14 \u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0430 \u0432\u0441\u0451 \u043c\u0438\u043d\u0443\u0441 1 \u0441\u0435\u043a\u0443\u043d\u0434\u0430 \u043d\u0430 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443) \u043d\u0430 1.8 \u043c\u0438\u043b\u043b\u0438\u0430\u0440\u0434\u043e\u0432 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u2014 \u0442\u043e \u0435\u0441\u0442\u044c, \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 7 \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0430 \u0432\u044b\u0437\u043e\u0432. \u0417\u0432\u0443\u0447\u0438\u0442 \u0440\u0430\u0437\u0443\u043c\u043d\u043e.<\/p>\n<p>  <\/p>\n<h2 id=\"urodlivyy-podhod\">\u0423\u0440\u043e\u0434\u043b\u0438\u0432\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434<\/h2>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u0435 \u0441 \u044d\u043a\u0437\u0438\u0441\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439: \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u0447\u043d\u044b\u0439 (\u043c\u043e\u043d\u043e\u043c\u043e\u0440\u0444\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439) \u0442\u0438\u043f <code>wc<\/code> \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 \u0432\u044b\u0437\u043e\u0432\u0430. \u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u0443 \u043d\u0430\u0441 \u0431\u044b \u0431\u044b\u043b\u043e \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">main = do   -- ..   case stats of        [Words] -&gt; print $ wc @'Words contents        [Bytes] -&gt; print $ wc @'Bytes contents        [Lines] -&gt; print $ wc @'Lines contents        [Words, Bytes] -&gt; print $ wc @('Words '::: 'Bytes) contents        [Lines, Bytes] -&gt; print $ wc @('Lines '::: 'Bytes) contents        -- ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041d\u043e \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u043f\u044f\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u0442\u043e \u0448\u043a\u043e\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0438\u043a\u0430 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043d\u0430\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/7bf\/52c\/c2e\/7bf52cc2e279f0bfde28e3f86371a1b7.svg\" alt=\"$2^5 - 1 = 31$\" data-tex=\"inline\"><\/math> \u0432\u0435\u0442\u043a\u0430 \u0432 <code>case<\/code>. \u041f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0438\u0445 \u0432\u0441\u0435 \u2014 \u043d\u0435 \u0432\u044b\u0445\u043e\u0434.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0447\u044c \u0438\u0445 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c, \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0440\u0438\u0431\u0435\u0433\u043d\u0443\u0442\u044c \u043a Template Haskell. \u041c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c (\u043c\u0435\u0442\u0430-)\u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>dispatch<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">  contents &lt;- unsafeMMapFile path   putStrLn $ $(dispatch 'wc 'contents) stats<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c <code>$(dispatch 'wc 'contents)<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u0435\u043b\u0430\u0435\u0442 <code>case<\/code>-\u0430\u043d\u0430\u043b\u0438\u0437 <code>stats<\/code> \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0439 \u0447\u0443\u0442\u044c \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 <code>dispatch<\/code> \u2014 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u0435 \u0432 Template Haskell, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">dispatch :: Name -&gt; Name -&gt; Q Exp dispatch fun bs = reify ''Statistics &gt;&gt;= \\case   TyConI (DataD _ _ _ _ cons _) -&gt; do     let consNames = [ name | NormalC name _ &lt;- cons ]     let powerset = filterM (const [True, False]) consNames     let matches = buildMatch fun bs &lt;$&gt; filter (not . null) powerset     fallbackMatch &lt;- (\\body -&gt; Match WildP (NormalB body) []) &lt;$&gt; [e| error &quot;Unexpected input&quot; |]     pure $ LamCaseE $ matches &lt;&gt; [fallbackMatch]   _ -&gt; fail &quot;unsupported type&quot;  buildMatch :: Name -&gt; Name -&gt; [Name] -&gt; Match buildMatch fun bs consNames = Match (ListP $ (`ConP` []) &lt;$&gt; consNames) (NormalB $ VarE 'show `AppE` (wcCall `AppE` VarE bs)) []   where     wcCall = VarE fun `AppTypeE` foldr1 f (PromotedT &lt;$&gt; consNames)     f accTy promotedTy = PromotedT '(:::) `AppT` accTy `AppT` promotedTy<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u043e\u0432\u0441\u0435\u043c \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0442\u043e \u043c\u044b \u0443\u0437\u043d\u0430\u0451\u043c \u0432\u0441\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0442\u0438\u043f\u0430 <code>Statistics<\/code> (\u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u043a\u0441\u0442\u0430\u0442\u0438, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e), \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u0435\u043f\u0443\u0441\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 (\u0442\u043e \u0435\u0441\u0442\u044c, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u0435\u043f\u0443\u0441\u0442\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 <code>powerset<\/code>) \u043c\u044b \u0441\u0442\u0440\u043e\u0438\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e <code>case<\/code>-\u0432\u0435\u0442\u043a\u0443 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>buildMatch<\/code>. \u0412\u0441\u0435 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0442\u043a\u0438 \u043c\u044b \u0437\u0430\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432 \u043e\u0434\u0438\u043d \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043b\u044f\u043c\u0431\u0434\u0430-<code>case<\/code> (\u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c <code>{-# LANGUAGE LambdaCase #-}<\/code>).<\/p>\n<p>  <\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0437\u0430\u0431\u0430\u0432\u043d\u043e, \u0447\u0442\u043e \u0442\u0443\u0442 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0437\u0430\u0431\u0438\u0442\u044c \u043d\u0430 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u0442\u043e\u0442\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0438 \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u044b\u043b\u0435\u0437\u0443\u0442 \u0442\u043e\u0433\u0434\u0430 \u0436\u0435.<\/p>\n<p>  <\/p>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0449\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044f \u043a\u043e\u0440\u043e\u0431\u0438\u0442 (\u043d\u0443, \u043a\u0440\u043e\u043c\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f TH) \u2014 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0436\u0438\u0434\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 <code>stats<\/code> \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c. \u041c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u0442\u044c \u044d\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438. \u0421 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">  let selectedStats = map snd $ filter fst [ (countBytes, Bytes), (countChars, Chars)                                            , (countWords, Words), (countMaxLineLength, MaxLL)                                            , (countLines, Lines)                                            ]<\/code><\/pre>\n<p>  <\/p>\n<p>\u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443, \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u043c\u043e\u043c\u0443 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 <code>Ord<\/code>. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u044f\u0432\u043d\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a <code>stats<\/code>. \u041e\u0431\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442, \u043e\u0434\u043d\u0430\u043a\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0443\u0442\u044c \u0447\u0438\u0449\u0435 \u0438 \u043d\u0430\u0434\u0451\u0436\u043d\u0435\u0435, \u0430 \u043f\u043e\u0442\u0435\u0440\u0438 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438\u0437-\u0437\u0430 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 <code>stats<\/code>, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0436\u0438\u043c\u043e \u043c\u0430\u043b\u044b.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043b\u043e\u0436\u0438\u043c \u0432\u0441\u0435 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 \u0432\u043c\u0435\u0441\u0442\u0435!<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">main :: IO () main = do   Options { .. } &lt;- execParser $ info (options &lt;**&gt; helper) (fullDesc &lt;&gt; progDesc &quot;Print newline, word, and byte counts for each file&quot;)   let selectedStats = map snd $ filter fst [ (countBytes, Bytes), (countChars, Chars)                                            , (countWords, Words), (countMaxLineLength, MaxLL)                                            , (countLines, Lines)                                            ]   let stats | null selectedStats = [Bytes, Words, Lines]             | otherwise = selectedStats   forM_ files $ \\path -&gt; do     contents &lt;- unsafeMMapFile path     putStrLn $ $(dispatch 'wc 'contents) stats<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"okonchatelnaya-proizvoditelnost\">\u041e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/h3>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434? \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0432\u0441\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 (31 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u2014 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0431\u0435\u0440\u0443 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u0438\u0445 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u044f \u0441\u043d\u043e\u0432\u0430 \u0432\u043e\u0437\u044c\u043c\u0443 <code>wc<\/code> \u0438\u0437 GNU Coreutils \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u044d\u0442\u0438 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0445\u043e\u0442\u044c \u043a \u0447\u0435\u043c\u0443-\u0442\u043e. \u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u0432\u0441\u0435\u0433\u0434\u0430: \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0435\u0441\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f 5 \u0440\u0430\u0437 \u043d\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u0432 1.8 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442, \u0438 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0432 \u044e\u0437\u0435\u0440\u0441\u043f\u0435\u0439\u0441\u0435. <code>wc<\/code> \u0438\u0437 Coreutils \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f <code>LC_ALL=C LANG=C<\/code>, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0438\u043d\u043e\u0435.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b:<\/p>\n<p>  <\/p>\n<div class=\"scrollable-table\">\n<table>\n<thead>\n<tr>\n<th>\u0421\u043b\u043e\u0432\u0430<\/th>\n<th>\u0411\u0430\u0439\u0442\u044b<\/th>\n<th>\u0421\u0442\u0440\u043e\u043a\u0438<\/th>\n<th>\u0421\u0438\u043c\u0432\u043e\u043b\u044b<\/th>\n<th>\u0414\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438<\/th>\n<th>Haskell <code>wc<\/code>, \u0441<\/th>\n<th>Coreutils <code>wc<\/code>, \u0441<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><\/td>\n<td>\u2713<\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>0.00 \u00b9<\/td>\n<td>0.00 \u00b9<\/td>\n<\/tr>\n<tr>\n<td>\u2713<\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>1.54<\/td>\n<td>12.5<\/td>\n<\/tr>\n<tr>\n<td>\u2713<\/td>\n<td>\u2713<\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>1.20<\/td>\n<td>12.5<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<td>\u2713<\/td>\n<td><\/td>\n<td><\/td>\n<td>1.06 \/ 0.24 \u00b2<\/td>\n<td>0.26<\/td>\n<\/tr>\n<tr>\n<td>\u2713<\/td>\n<td>\u2713<\/td>\n<td>\u2713<\/td>\n<td><\/td>\n<td><\/td>\n<td>1.52<\/td>\n<td>12.5<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>\u2713<\/td>\n<td><\/td>\n<td>1.42<\/td>\n<td>8.45 \u00b3<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>\u2713<\/td>\n<td>2.21<\/td>\n<td>12.5<\/td>\n<\/tr>\n<tr>\n<td>\u2713<\/td>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>\u2713<\/td>\n<td>2.92<\/td>\n<td>12.5<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  <\/p>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u041c\u043d\u0435 \u0432\u0441\u0451 \u0435\u0449\u0451 \u0440\u0432\u0451\u0442 \u0448\u0430\u0431\u043b\u043e\u043d, \u0447\u0442\u043e \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u0431\u0430\u0439\u0442 <em>\u0438<\/em> \u0441\u043b\u043e\u0432 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043e\u0434\u043d\u0438\u0445 \u043b\u0438\u0448\u044c \u0441\u043b\u043e\u0432.<\/li>\n<li>\u041f\u043e\u0445\u043e\u0436\u0435, \u0447\u0442\u043e \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 C \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a (\u0441\u043b\u043e\u0432\u0430, \u0431\u0430\u0439\u0442\u044b, \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u043b\u0438\u043d\u0443 \u0441\u0442\u0440\u043e\u043a) \u0435\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u043b\u0438\u0431\u043e \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u0441\u0442\u0440\u043e\u043a, \u043b\u0438\u0431\u043e \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b. \u042f \u043d\u0435 \u0443\u0434\u0438\u0432\u043b\u0451\u043d.<\/li>\n<li>\u00b9 \u0414\u0430, <code>time<\/code> \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 <code>0.00user<\/code> \u0434\u043b\u044f \u043e\u0431\u043e\u0438\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0431\u0430\u0439\u0442.<\/li>\n<li>\u00b2 \u041f\u0435\u0440\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0431\u0430\u0439\u0442 \u0438 \u0441\u0442\u0440\u043e\u043a (1.06 \u0441\u0435\u043a\u0443\u043d\u0434) \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441 \u0430\u043f\u0441\u0442\u0440\u0438\u043c\u043e\u0432\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 <code>bytestring<\/code>. \u0412\u0442\u043e\u0440\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u2014 \u0441 \u043f\u0440\u043e\u043f\u0430\u0442\u0447\u0435\u043d\u043d\u043e\u0439 <code>bytestring<\/code>, \u0433\u0434\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b\u0430 (<code>count<\/code>) \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c SIMD-\u0438\u043d\u0442\u0440\u0438\u043d\u0441\u0438\u043a\u043e\u0432. \u041f\u043e \u0438\u0440\u043e\u043d\u0438\u0438 \u0441\u0443\u0434\u044c\u0431\u044b \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f <code>count<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 C, \u0438, \u0447\u0442\u043e \u0441\u043d\u043e\u0432\u0430 \u0438\u0440\u043e\u043d\u0438\u0447\u043d\u043e, \u043a\u043e\u043c\u043f\u043b\u0438\u044f\u0442\u043e\u0440 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0435\u0451 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e, \u0438 \u0434\u0430\u0436\u0435 \u0447\u0438\u0441\u0442\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u0431\u044b\u043b\u0430 \u0431\u044b \u0431\u044b\u0441\u0442\u0440\u0435\u0435 (\u0445\u043e\u0442\u044f \u0438 \u043d\u0435 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u0441\u0442\u0440\u043e, \u043a\u0430\u043a \u0441 \u0440\u0443\u0447\u043d\u044b\u043c\u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 SIMD), \u043d\u043e \u0432\u0441\u044e \u044d\u0442\u0443 \u0438\u0440\u043e\u043d\u0438\u044e \u043b\u0443\u0447\u0448\u0435 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430.<\/li>\n<li>\u00b3 \u0417\u0434\u0435\u0441\u044c <code>wc<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441 UTF-8-\u043b\u043e\u043a\u0430\u043b\u044c\u044e, \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u043d\u0430\u0447\u0435 \u043e\u043d \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u0447\u0438\u0441\u043b\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0440\u0430\u0432\u043d\u043e \u0447\u0438\u0441\u043b\u0443 \u0431\u0430\u0439\u0442, \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0437\u0430 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u0437\u043c\u0435\u0440\u0438\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 UTF-8-\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0432\u043f\u043e\u043b\u043d\u0435 \u0441\u0435\u0431\u0435 \u043d\u0435\u043f\u043b\u043e\u0445\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b.<\/p>\n<p>  <\/p>\n<h1 id=\"vsyakie-melochi\">\u0412\u0441\u044f\u043a\u0438\u0435 \u043c\u0435\u043b\u043e\u0447\u0438<\/h1>\n<p>  <\/p>\n<p>\u041d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u043f\u0446\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, \u043e\u043d\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0435 \u0436\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438, \u0447\u0442\u043e \u0438 <code>wc<\/code>, \u043e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u043e\u0432. \u0427\u0442\u043e \u0435\u0449\u0451 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c?<\/p>\n<p>  <\/p>\n<h2 id=\"parallelizm\">\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c<\/h2>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043b\u0435\u0433\u043a\u043e: \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c <code>forM_<\/code> \u043d\u0430 <code>forConcurrently_<\/code> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <a href=\"http:\/\/hackage.haskell.org\/package\/async-2.2.2\/docs\/Control-Concurrent-Async.html#v:forConcurrently_\" rel=\"nofollow\">async<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">main :: IO () main = do   Options { .. } &lt;- execParser $ info (options &lt;**&gt; helper) (fullDesc &lt;&gt; progDesc &quot;Print newline, word, and byte counts for each file&quot;)   let selectedStats = map snd $ filter fst [ (countBytes, Bytes), (countChars, Chars)                                            , (countWords, Words), (countMaxLineLength, MaxLL)                                            , (countLines, Lines)                                            ]   let stats | null selectedStats = [Bytes, Words, Lines]             | otherwise = selectedStats   forConcurrently_ files $ \\path -&gt; do     contents &lt;- unsafeMMapFile path     putStrLn $ $(dispatch 'wc 'contents) stats<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0435 \u0444\u0430\u0439\u043b\u043e\u0432, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u044f\u0434\u0435\u0440 (\u0432\u0435\u0440\u043d\u0435\u0435, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044f\u0434\u0435\u0440 \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u0430\u0441\u043a\u0435\u043b\u0435\u0432\u0441\u043a\u043e\u043c\u0443 RTS, \u0447\u0442\u043e \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0440\u0430\u0432\u043d\u043e \u043f\u043e\u043b\u043d\u043e\u043c\u0443 \u0447\u0438\u0441\u043b\u0443 \u044f\u0434\u0435\u0440). \u0415\u0441\u043b\u0438 \u0431\u044b \u043d\u0430\u0441 \u044d\u0442\u043e \u043d\u0435 \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043b\u043e, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u043e\u043f\u0446\u0438\u044e \u0442\u0438\u043f\u0430 <code>-j<\/code>, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0441\u043b\u043e\u0436\u043d\u043e \u0438 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044e.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a\u043e\u0432 \u043e\u0432\u0435\u0440\u0445\u0435\u0434 \u044d\u0442\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u043c\u0430?<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u0441\u0447\u0451\u0442 \u0441\u043b\u043e\u0432 \u0438 \u0431\u0430\u0439\u0442 \u0432 \u043e\u0434\u043d\u043e\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u0437\u0430\u0439\u043c\u0451\u0442 1.22 \u0441\u0435\u043a\u0443\u043d\u0434 \u2014 \u043f\u043e\u0447\u0442\u0438 \u043a\u0430\u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f, \u0445\u043e\u0442\u044c \u0438 \u0434\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0432\u044b\u0448\u0435.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0436\u0435 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u044d\u0442\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u0441\u043a\u043e\u0440\u043c\u0438\u0432 \u0435\u0439 \u043d\u0430\u0448 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u0448\u0435\u0441\u0442\u044c \u0440\u0430\u0437 (\u043f\u043e \u0447\u0438\u0441\u043b\u0443 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u044f\u0434\u0435\u0440 \u0432 \u043c\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u0435), \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0432\u043d\u043e 1.47 \u0441\u0435\u043a\u0443\u043d\u0434, \u043d\u043e \u0441 \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0434\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u0435\u0439. \u0414\u0443\u043c\u0430\u044e, \u0447\u0442\u043e \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0441\u0451 \u0443\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  <\/p>\n<h2 id=\"krasivaya-pechat\">\u041a\u0440\u0430\u0441\u0438\u0432\u0430\u044f \u043f\u0435\u0447\u0430\u0442\u044c<\/h2>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043d\u0430\u0448\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u0442\u043e \u043e\u043d\u0430 \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0432\u0438\u0434\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">Tagged 123 ::: (Tagged 456 ::: Tagged 789)<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0434\u0440\u0443\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0442\u0430\u043a \u0447\u0442\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c! \u041f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043a\u043b\u0430\u0441\u0441 <code>Statistic<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">class Statistic s res st comp | res -&gt; s, st -&gt; s                               , s -&gt; res, s -&gt; st, s -&gt; comp where   -- ...   prettyPrint :: res -&gt; String<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0433\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a \u043f\u0440\u043e\u0441\u0442\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">instance Statistic 'Bytes (Tagged 'Bytes) (Tagged 'Bytes) 'Chunked where   -- ...   prettyPrint (Tagged n) = show n &lt;&gt; &quot; bytes&quot;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a \u0442\u043e\u0436\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0438\u0441\u0430\u043d\u0438\u043d\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">  prettyPrint (a ::: b) = prettyPrint a &lt;&gt; &quot;\\n&quot; &lt;&gt; prettyPrint b<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>buildMatch<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430 <code>prettyPrint<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>show<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">buildMatch fun bs consNames = Match (ListP $ (`ConP` []) &lt;$&gt; consNames) (NormalB $ VarE 'prettyPrint `AppE` (wcCall `AppE` VarE bs)) []<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418 \u0432\u0441\u0451!<\/p>\n<p>  <\/p>\n<h2 id=\"bolshe-vidov-vhodnyh-dannyh\">\u0411\u043e\u043b\u044c\u0448\u0435 \u0432\u0438\u0434\u043e\u0432 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>  <\/p>\n<p>\u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0444\u0430\u0439\u043b \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e <code>mmap<\/code>\u043d\u0443\u0442\u044c. \u041e\u0434\u043d\u0430\u043a\u043e, \u0442\u0430\u043a \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430: \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430\u0448\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 <code>hwc &lt;(cat foo | grep bar)<\/code>.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044f, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u043f\u0443\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u043c \u0444\u0430\u0439\u043b\u043e\u043c \u0438\u043b\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u043e\u0439 \u2014 \u0438\u0445-\u0442\u043e <code>mmap<\/code>\u0438\u0442\u044c \u043c\u043e\u0436\u043d\u043e. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u044b \u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0434\u0430\u0436\u0435 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f <code>mmap<\/code>\u0438\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0438\u0434\u044b \u043f\u0443\u0442\u0435\u0439. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0445 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0432 <em>\u043b\u0435\u043d\u0438\u0432\u0443\u044e<\/em> <code>ByteString<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0451 \u0435\u0449\u0451 \u0431\u044b\u043b\u0430 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u043e\u0439. \u0410 \u043b\u0435\u043d\u0438\u0432\u0430\u044f <code>ByteString<\/code> \u2014 \u044d\u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u0442\u0440\u043e\u0433\u0438\u0445 \u0447\u0430\u043d\u043a\u043e\u0432, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e \u043d\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0447\u0430\u043d\u043a\u043e\u0432\u044b\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">import qualified Data.ByteString.Lazy as BSL  wcLazy :: forall s res st comp. Statistic s res st comp =&gt; BSL.ByteString -&gt; res wcLazy s = extractState $! runCompute computation   where     runCompute :: StatComputation st comp -&gt; st     runCompute (ByteOnlyComputation step) = BSL.foldl' step initState s     runCompute (ChunkedComputation _ chunker) = BSL.foldlChunks chunker initState s<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 <code>main<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">  forConcurrently_ files $ \\path -&gt; do     stat &lt;- getFileStatus path     if isRegularFile stat || isSymbolicLink stat       then countStrict stats $ unsafeMMapFile path       else countLazy stats $ BSL.readFile path<\/code><\/pre>\n<p>  <\/p>\n<p>\u0433\u0434\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0434\u0432\u0435 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0445 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">  where     countStrict stats act = do       contents &lt;- act       putStrLn $ $(dispatch 'wc 'contents) stats     countLazy stats act = do       contents &lt;- act       putStrLn $ $(dispatch 'wcLazy 'contents) stats<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418 \u0432\u0441\u0451!<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>wcLazy<\/code> \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0442\u0430\u0439\u043f\u043a\u043b\u0430\u0441\u0441, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0442\u0438\u043f \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u0445 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u043e \u0434\u0432\u0435 \u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u0442\u043e \u043f\u043e\u043b\u044c\u0437\u044b \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u043b\u043e.<\/p>\n<p>  <\/p>\n<h2 id=\"podderzhka-stdin\">\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 stdin<\/h2>\n<p>  <\/p>\n<p>\u0415\u0449\u0451 \u043e\u0434\u043d\u0430 \u0432\u0435\u0449\u044c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0443\u043c\u0435\u0435\u0442 Coreutils <code>wc<\/code>, \u043d\u043e \u043d\u0435 \u0443\u043c\u0435\u0435\u0442 \u043d\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u2014 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 <code>stdin<\/code>. \u0418\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432 \u043a\u043e\u043d\u0435\u0446 <code>main<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">main = do   -- ... as before ...    when (null files) $ countLazy stats BSL.getContents<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">cat testfile.txt | \/usr\/bin\/time hwc-exe -cw<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0445\u0443\u0436\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438? \u041d\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0448\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0437\u0430 1.40 \u0441\u0435\u043a\u0443\u043d\u0434 \u2014 \u0442\u043e \u0435\u0441\u0442\u044c, \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0441 1.22 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u043c\u0438 \u0440\u0430\u043d\u0435\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u0441\u0435\u0431\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u0430.<\/p>\n<p>  <\/p>\n<h2 id=\"vremya-kompilyacii-i-raspuhanie-koda\">\u0412\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438 \u0440\u0430\u0441\u043f\u0443\u0445\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430<\/h2>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0434\u0438\u0440\u0430\u044e\u0441\u044c, \u043d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u0443\u043f\u043e\u043c\u044f\u043d\u0435\u043c \u0440\u0430\u0434\u0438 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438: \u043a\u0430\u043a\u043e\u0432 \u043e\u0432\u0435\u0440\u0445\u0435\u0434 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f? \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043b\u0438\u0431\u043e \u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u043b\u0438\u0431\u043e \u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0444\u0430\u0439\u043b\u0430, \u0442\u0430\u043a \u0447\u0442\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0431\u0435 \u044d\u0442\u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438!<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u0439\u0434\u0451\u043c \u043f\u043e \u00ab\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439\u00bb \u0434\u043e\u0440\u043e\u0433\u0435 (\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0447\u0435\u043c-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u0431\u0430\u0437\u044b \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435), \u0442\u043e <code>stack build<\/code> \u0437\u0430\u0439\u043c\u0451\u0442 7.9 \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0440\u0430\u0432\u0435\u043d 2.24 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u0430 (\u043f\u043e\u0441\u043b\u0435 <code>strip<\/code>).<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u0445\u043e\u0434 \u0441 Template Haskell \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0440\u043e\u0432\u043d\u043e \u0432\u0442\u0440\u043e\u0435 \u0434\u043e\u043b\u044c\u0448\u0435: 23 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u0438 \u043d\u0435 \u0440\u0430\u0441\u043f\u0443\u0445 \u0442\u043e\u043b\u043a\u043e\u043c (\u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f 31 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438): \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0430\u043b 2.34 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u0430, \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u2014 4.3%.<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0442\u044f\u2026 \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 <code>stack build<\/code> (\u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0431\u043e\u0440\u043a\u0430 \u0441 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438). <code>stack build --fast<\/code> \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043a\u0443\u0434\u0430 \u0431\u044b\u0441\u0442\u0440\u0435\u0435.<\/p>\n<p>  <\/p>\n<p>\u00ab\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f\u00bb \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0437\u0430 5.6 \u0441\u0435\u043a\u0443\u043d\u0434 \u0441 <code>--fast<\/code>, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u0432\u0435\u0440\u0441\u0438\u044f \u0441 TH \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u2026 7.8 \u0441\u0435\u043a\u0443\u043d\u0434. \u0422\u0443\u0442 \u0443\u0436\u0435 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u043d\u0435 \u0442\u0430\u043a\u0430\u044f \u0443\u0436 \u0438 \u0431\u043e\u043b\u044c\u0448\u0430\u044f. \u0421 \u044d\u0442\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0436\u0438\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u0418 \u044f \u0437\u043d\u0430\u044e, \u0447\u0442\u043e \u0434\u043b\u044f \u0447\u0430\u0441\u0442\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u044b\u0439 \u0444\u0430\u043a\u0442\u043e\u0440, \u0442\u0430\u043a \u0447\u0442\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 \u0440\u0435\u043b\u0438\u0437\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430 \u0441 C. \u041a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u0445\u0430\u0441\u043a\u0435\u043b\u044c \u0437\u0434\u0435\u0441\u044c \u0441\u043b\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0434\u0447\u0438\u0441\u0442\u0443\u044e: \u043d\u0430 \u043c\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 <code>wc<\/code> \u0438\u0437 GNU Coreutils \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0437\u0430 0.06 \u0441\u0435\u043a\u0443\u043d\u0434, \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430 \u2014 21 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442. \u0411\u0438\u043d\u0430\u0440\u043d\u0438\u043a <code>wc<\/code> \u0441 \u0443\u0431\u0443\u043d\u0442\u044b \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 24 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442\u0430. \u0412 100 \u0440\u0430\u0437 \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u0445\u0430\u0441\u043a\u0435\u043b\u044c!<\/p>\n<p>  <\/p>\n<p>\u041d\u0443, \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u043b\u043e\u0447\u0438 \u0438 \u043f\u0440\u0438\u0434\u0438\u0440\u043a\u0438 \u043c\u043d\u0435 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u044f\u0442\u044c\u0441\u044f \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044e.<\/p>\n<p>  <\/p>\n<h1 id=\"zaklyuchenie\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c? \u0415\u0441\u043b\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0442\u043e \u043c\u044b \u043f\u0440\u0438\u0432\u0435\u043b\u0438 \u043d\u0430\u0448 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f <code>wc<\/code> \u043a \u0432\u0438\u0434\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0443\u0434\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 Unix-\u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0448 \u0445\u0430\u0441\u043a\u0435\u043b\u044c-<code>wc<\/code> \u0433\u043e\u0442\u043e\u0432 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u043e GNU Coreutils <code>wc<\/code>. \u0421\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u043e\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u043e\u043f\u0446\u0438\u0438 (\u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a!), \u0434\u0430 \u0442\u0430\u043a, \u0447\u0442\u043e \u043e\u043d \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u043b\u0438\u0448\u044c \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441 \u043e\u043a\u043e\u043b\u043e\u043d\u0443\u043b\u0435\u0432\u044b\u043c \u043e\u0432\u0435\u0440\u0445\u0435\u0434\u043e\u043c \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u044f\u0440\u0438\u0437\u0430\u0446\u0438\u044e. \u0417\u0430\u0431\u0430\u0432\u043d\u043e, \u0447\u0442\u043e \u0432 \u043a\u0430\u043a\u043e\u043c-\u0442\u043e \u0441\u043c\u044b\u0441\u043b\u0435 \u0443 \u043d\u0430\u0441 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043a\u0443\u0434\u0430 \u0431\u043b\u0438\u0436\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 \u00ab\u043d\u0435 \u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0437\u0430 \u0442\u043e, \u0447\u0442\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0448\u044c\u00bb, \u0442\u0430\u043a \u043c\u0438\u043b\u043e\u043c\u0443 \u0441\u0435\u0440\u0434\u0446\u0430\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u043e\u0432 \u043d\u0430 C \u0438 C++, \u0447\u0435\u043c \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 C.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e, \u0442\u043e \u043c\u044b:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u043b\u0438 \u043d\u0430\u0448 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f <code>wc<\/code> \u043d\u0430 \u043d\u0430\u0431\u043e\u0440 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0445, \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445, \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0438 \u043a\u043e\u043c\u043f\u043e\u0437\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u0443\u0441\u043e\u0447\u043a\u043e\u0432, \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043d\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443;<\/li>\n<li>\u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u0442\u044c \u044d\u0442\u0438 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 \u0432\u043c\u0435\u0441\u0442\u0435;<\/li>\n<li>\u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0442\u0435\u0441\u0442\u044b \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0431\u0443\u0434\u0443\u0447\u0438 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u043c\u0438, \u0447\u0442\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u043e\u043d\u0438 \u0442\u043e\u0436\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432 \u043b\u044e\u0431\u044b\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f\u0445 \u043f\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044e;<\/li>\n<li>\u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0438\u0441\u044c \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u0432\u044b\u0431\u0440\u0430\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0442\u0435\u0445\u043d\u0438\u043a\u0438, \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u0451\u043d\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438, \u0438 \u043f\u043e\u043b\u044e\u0431\u043e\u0432\u0430\u043b\u0438\u0441\u044c, \u043a\u0430\u043a \u043a\u0440\u0430\u0441\u043e\u0447\u043d\u043e \u0438 \u0433\u0440\u043e\u043c\u043a\u043e \u044d\u0442\u0438 \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u0441\u043b\u0438\u0432\u0430\u044e\u0442 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0445\u0430\u0441\u043a\u0435\u043b\u044f;<\/li>\n<li>\u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0435\u043b\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u043f\u0446\u0438\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Template Haskell;<\/li>\n<li>\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438, \u0447\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0435\u0441\u044c\u043c\u0430 \u0431\u043b\u0438\u0437\u043e\u043a \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a \u043d\u0430\u0448\u0435\u0439 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u0432\u0441\u044f \u044d\u0442\u0430 \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043b\u0438\u044f\u043d\u0438\u044f \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c;<\/li>\n<li>\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0435\u043b\u043a\u0438\u0445 \u0444\u0438\u0447, \u043e\u0442 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u0430.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0438\u0435 \u0434\u0435\u043b\u0430.<\/p>\n<p>  <\/p>\n<p>\u0410, \u043d\u0443 \u0438 \u0441\u0442\u043e\u0438\u0442 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c \u0435\u0449\u0451 \u0434\u0432\u0435 \u0432\u0435\u0449\u0438:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u041d\u0430\u0448 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441 \u043f\u043e\u043b\u0443\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u0436\u0438\u0437\u043d\u0435\u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d. \u041c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0435 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0431\u0430\u0439\u0442, \u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0435 16-32 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442\u0430 (\u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443 \u043a\u044d\u0448\u0430 L1). \u041d\u0435\u0442\u0440\u0443\u0434\u043d\u043e \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 7 \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434, \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u0444\u0430\u0439\u043b\u0430 \u0432 1.8 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442 \u044d\u0442\u043e \u0434\u0430\u043b\u043e \u0431\u044b \u043e\u0432\u0435\u0440\u0445\u0435\u0434 \u0432 0.4 \u043c\u0441, \u0438\u043b\u0438 0.04%. \u041d\u043e \u0442\u043e\u0433\u0434\u0430 \u0431\u044b \u043d\u0430\u043c \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0438\u0433\u0440\u0430\u0442\u044c\u0441\u044f \u0441 Template Haskell!<\/li>\n<li>\u041d\u0430\u0448\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u043c \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043e\u043c <code>wc<\/code>, \u043a\u043e\u0435-\u0447\u0442\u043e \u043e\u043d\u0430 \u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438, \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u0442 UTF-8 \u0438\u043b\u0438 ASCII, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a <code>wc<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u044e, \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u044f \u0432\u0441\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043f\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 glibc. \u041d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0448\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0447\u0435\u0433\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e, \u0438, \u0447\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430, \u0441\u043a\u0430\u0436\u0435\u043c, \u043f\u043e\u0434\u0441\u0447\u0451\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0442\u0440\u043e\u043a \u0438\u043b\u0438 \u0441\u043b\u043e\u0432. \u041d\u043e \u043f\u0440\u043e \u00ab\u043d\u0435 \u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0437\u0430 \u0442\u043e, \u0447\u0442\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0448\u044c\u00bb \u044f \u0443\u0436\u0435 \u043f\u0438\u0441\u0430\u043b \u0447\u0443\u0442\u044c \u0432\u044b\u0448\u0435.<\/li>\n<\/ol>\n<\/div>\n<p> \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\/post\/496370\/\"> https:\/\/habr.com\/ru\/post\/496370\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/496370\/\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440.<\/p>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, <a href=\"https:\/\/habr.com\/post\/489136\/\">\u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437<\/a> \u043c\u044b \u044d\u043c\u043f\u0438\u0440\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u043a\u0430\u0437\u0430\u043b\u0438, \u0447\u0442\u043e \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0430\u043a\u0438\u0439 \u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439 wc, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 wc \u0438\u0437 GNU Coreutils. \u041f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0434\u0435\u043b\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0447\u0435\u0441\u0442\u043d\u043e\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435: \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0435 \u0443\u043c\u0435\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0431\u0430\u0439\u0442, \u0441\u0442\u0440\u043e\u043a \u0438 \u0441\u043b\u043e\u0432, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 wc \u043a\u0443\u0434\u0430 \u043c\u043e\u0449\u043d\u0435\u0435: \u043e\u043d \u0438\u043c\u0435\u0435\u0442 \u0435\u0449\u0451 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043e\u043f\u0446\u0438\u0438, \u0443\u043c\u0435\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c \u0438\u0437 stdin\u2026 \u041a\u043e\u0440\u043e\u0447\u0435, \u0443 \u043d\u0430\u0441 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0438\u0433\u0440\u0443\u0448\u043a\u0430.<\/p>\n<p>  <\/p>\n<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c. \u041d\u0430\u0448\u0430 \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u2014 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u0410 \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f \u043a \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0432\u044b\u0434\u0435\u043b\u044f\u044f \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u044e\u043d\u0438\u0442.<\/p>\n<p>  <\/p>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 <a href=\"https:\/\/github.com\/coreutils\/coreutils\/blob\/master\/src\/wc.c\" rel=\"nofollow\">C-\u0432\u0435\u0440\u0441\u0438\u044e<\/a> \u2014 \u043d\u0443, \u043b\u0438\u0447\u043d\u043e \u044f \u0431\u044b \u043d\u0435 \u043d\u0430\u0437\u0432\u0430\u043b \u044d\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u0446\u043e\u043c \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0433\u043e \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u043c \u0432\u0441\u0451 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 370 \u0441\u0442\u0440\u043e\u043a. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0430\u0440\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/rm\/rk\/d0\/rmrkd0k9gjyumqz6fmjbxsooovi.png\"><\/div>\n<p>  <\/p>\n<p><em>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0421-\u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0435 \u0432\u043b\u0435\u0437\u043b\u0430 \u043d\u0430 4k-\u044d\u043a\u0440\u0430\u043d \u0432 \u043f\u043e\u0440\u0442\u0440\u0435\u0442\u043d\u043e\u0439 \u043e\u0440\u0438\u0435\u043d\u0442\u0430\u0446\u0438\u0438 4-\u043c \u0448\u0440\u0438\u0444\u0442\u043e\u043c.<\/em><\/p>\n<p>  <\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0439 \u043c\u043e\u0434\u0443\u043b\u044f\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u044b, \u0441\u0440\u0435\u0434\u0438 \u043f\u0440\u043e\u0447\u0435\u0433\u043e:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u044b\u0440\u0430\u0437\u0438\u043c \u0438\u0434\u0435\u044e, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0432\u0440\u043e\u0434\u0435 \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u0447\u0438\u0441\u043b\u0430 \u0431\u0430\u0439\u0442 \u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0435\u0435 \u043d\u0430 \u0432\u0441\u0451\u043c \u0432\u0445\u043e\u0434\u0435 \u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0431\u0430\u0439\u0442;<\/li>\n<li>\u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a, \u043d\u0430\u0441\u043b\u0430\u0436\u0434\u0430\u044f\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043d\u0438\u0445 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 (\u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 local reasoning);<\/li>\n<li>\u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u043e\u0432, \u043d\u0430\u0441\u043b\u0430\u0436\u0434\u0430\u044f\u0441\u044c local reasoning&#8217;\u043e\u043c \u0435\u0449\u0451 \u0440\u0430\u0437;<\/li>\n<li>\u0438\u0441\u043f\u044b\u0442\u0430\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0447\u0442\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u043a\u0438, \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439, \u043d\u043e \u0444\u0435\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u043e\u0440\u043c\u043e\u0437\u044f\u0449\u0438\u0439 \u043a\u043e\u0434;<\/li>\n<li>\u043f\u043e\u0438\u0433\u0440\u0430\u0435\u043c \u0441 Template Haskell;<\/li>\n<li>\u043f\u043e\u043b\u044e\u0431\u0443\u0435\u043c\u0441\u044f (\u043d\u0435)\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0441\u0442\u044c\u044e \u0438 (\u043d\u0435)\u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430.<\/li>\n<\/ul>\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-301611","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/301611","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=301611"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/301611\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=301611"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=301611"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=301611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}