{"action":"created","comment":{"url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/comments/53319317","id":53319317,"diff_hunk":"@@ -0,0 +1,171 @@\n+# Хиндли-Милнер и Я\n+\n+## Какого ты типа?\n+\n+Если вы новичок в функциональном мире, то пройдет совсем немного времени прежде, чем вы погрузитесь в сигнатуры типов достаточно глубоко. Типы — это метаязык, который позволяет людям с самым различным бэкграундом общаться емко и эффективно. Большинство из них написанны в системе Хиндли-Милнера, которую мы вместе рассмотрим в этой главе.\n+\n+Когда работаешь с чистыми функциями, сигнатуры типов имеют выразительную мощь, с которой не сравнится никакой естественный язык. Эти сигнатуры шепчут вам о сокровенных секретах функций. В одну простую, компактную строку они вмещают описание поведения и цели функции. Из них мы можем вывести \"бесплатные теоремы\". Типы могут быть описаны таким образом, что не будет необходимости в явных анотациях. Они могут быть настроены довольно точно или описывать все в общем и абстрактном свете. Они пригодны не только для проверок на этапе компиляции, но также могут служить отличной документацией. Таким образом, сигнатуры типов играют важную роль в функциональном программировании — намного большую, чем вы могли ожидать вначале.\n+\n+JavaScript — динамический язык, но это не означает, что мы все избегаем типов данных. Мы всё еще работаем со строками, числами, булевским типом и так далее. Просто нет каких-либо средств на уровне языка, так что мы должны держать всё это в голове. Не беспокойтесь, если мы используем сигнатуры для документирования, мы можем заставить комментарии послужить нашим целям.\n+\n+Доступны утилиты для проверки типов, такие как [Flow](http://flowtype.org/) или даже типизированные диалекты — [TypeScript](http://www.typescriptlang.org/). Целью этой книги является снабжение вас инструментами для написания функционального кода, так что мы будем придерживаться стандартной системы типов используемой в функциональных языках.\n+\n+## Байки из Скрипта\n+\n+С пыльных страниц математических томов, сквозь глубокое моге белых листов, посреди обыкновенных записей в блогах по субботним утрам, приближаясь всё ближе к исходному коду, мы находим сигнатуры типов Хиндли-Милнера. Система довольно проста, но гарантирует быстрое объяснение и некоторые практики, которые полностью покрывают небольшой язык.\n+\n+```js\n+//  capitalize :: String -> String\n+var capitalize = function(s){\n+  return toUpperCase(head(s)) + toLowerCase(tail(s));\n+}\n+\n+capitalize(\"smurf\");\n+//=> \"Smurf\"\n+```\n+\n+Здесь `capitalize` принимет `String` и возвращает тоже `String`. Не думайте о реализации, нас интересует сигнатура типов. \n+\n+В системе Хиндли-Милнера функции записываются как `a -> b`, где `a` и `b` — это переменные того или иного типа. Так что сигнатура функции `capitalize` может быть прочтена как \"функция из `String` в `String`\". Другими словами, она принимает на вход `String` и возвращает `String` в качестве результата.\n+\n+Давайте посмотрим еще на несколько сигнатур:\n+\n+```js\n+//  strLength :: String -> Number\n+var strLength = function(s){\n+  return s.length;\n+}\n+\n+//  join :: String -> [String] -> String\n+var join = curry(function(what, xs){\n+  return xs.join(what);\n+});\n+\n+//  match :: Regex -> String -> [String]\n+var match = curry(function(reg, s){\n+  return s.match(reg);\n+});\n+\n+//  replace :: Regex -> String -> String -> String\n+var replace = curry(function(reg, sub, s){\n+  return s.replace(reg, sub);\n+});\n+```\n+\n+В `strLength` та же идея, что и прежде. Мы берем тип `String` и возрвщаем тип `Number`.\n+\n+Другие примеры могут озадачить на первый взгляд. Без полноценного понимания всех деталей, вы всегда можете видеть последний тип, значения которого и возвращаются. Так что функция `match` может быть интерпретирована так: она берет `Regex` и `String` и возвращает вам `[String]`. Но здесь происходит интересная вещь, и я бы хотел объяснить вам это, если можно.\n+\n+Для `match` мы можем сгруппировать сигнатуры следуюшим образом:\n+\n+```js\n+//  match :: Regex -> (String -> [String])\n+var match = curry(function(reg, s){\n+  return s.match(reg);\n+});\n+```\n+\n+Ах да, группировка последней части в круглые скобки предоставляет нам больше сведений. Теперь мы видим ее как функцию, которая принимает `Regex` и возвращает функцию из `String` в `[String]`. Вот что происходит на самом деле из-за каррирования: передвая функции `Regex` мы получаем другую функцию, которая ожидает в качестве аргумента `String`. Конечно, нам не обязательно думать в таком ключе каждый раз, но полезно понимать откуда и как возвращается последний тип.\n+\n+```js\n+//  match :: Regex -> (String -> [String])\n+\n+//  onHoliday :: String -> [String]\n+var onHoliday = match(/holiday/ig);\n+```\n+\n+Каждый аргумент вытасквиается с левого края сигнатуры. `onHoliday` — это `match` у которого уже есть `Regex`.\n+\n+```js\n+//  replace :: Regex -> (String -> (String -> String))\n+var replace = curry(function(reg, sub, s){\n+  return s.replace(reg, sub);\n+});\n+```\n+\n+Как вы можете видеть, все эти круглые скобки в `replace` являются слегка трудными для чтения и кажутся излишними, так что мы просто опустим их. Мы можем взять все аргументы сразу, если если решим, что проще думать о них так: `replace` принимает  `Regex`, `String`, другой `String` и в конце возвращает `String`.\n+\n+Еще пару штук, напоследок:\n+\n+```js\n+//  id :: a -> a\n+var id = function(x){ return x; }\n+\n+//  map :: (a -> b) -> [a] -> [b]\n+var map = curry(function(f, xs){\n+  return xs.map(f);\n+});\n+```\n+\n+Функция `id` принимет любой тип `a` и возвращает что-то того же типа `a`. Мы можем использовать переменные любых типов в коде вроде этого. Имена переменных, такие как `a` и `b` — это соглашение, но они произвольны и могут быть заменены на переменные с любым именем, каким вы захотите. Если это одни и те же переменные, то у них должен быть один и тот же тип. Это важное правило, так что давайте повторим: `a` -> `b` — может быть любого типа `a` и любого типа `b`, но `a -> a` означает, что это это один и тот же тип. Например, `id` может быть `String -> String` или `Number -> Number`, но не `String -> Bool`.\n+\n+Таким же образом `map` использует типизированные переменные, но но в этот раз мы представляем `b` который может быть (а может и не быть) того же типа, что и `a`. Мы можем прочитать это так: `map` принимает функцию из любого типа `a` в такой же тип или в другой тип `b`, затем принимает массив переменных типа `a` и в результате передает массив типов `b`.\n+\n+Будем надеятся, что вас захватила выразительная красота этой сигнатуры. Она буквально говорит что делает функция, почти слово в слово. Дана функция из `a` в `b`, массив типа `a` и эта функция даст нам массив типа `b`. Единственно здравая вещь, которую должна делать эта функция — это применить кровавую функцию к каждому `a`. Все остальное — гнусная ложь.\n+\n+Возможность рассуждать о типах и их смысле — это навык, с которым вы далеко пойдете в функциональном мире. Не только статьи, блоги, документации и прочее станет более доступным, кроме того, сами сигнатуры будут полезными анотациями о функциональности. Требуется практика, чтобы свободно читать их, но если вы уделите этому время, то куча информации станет доступна вам без  чтения подробных мануалов.\n+\n+Вот еще немного, просто чтобы посмотреть, сможете ли вы расшифровать их сами.\n+\n+```js\n+//  head :: [a] -> a\n+var head = function(xs){ return xs[0]; }\n+\n+//  filter :: (a -> Bool) -> [a] -> [a]\n+var filter = curry(function(f, xs){\n+  return xs.filter(f);\n+});\n+\n+//  reduce :: (b -> a -> b) -> b -> [a] -> b\n+var reduce = curry(function(f, x, xs){\n+  return xs.reduce(f, x);\n+});\n+```\n+\n+Возможно, `reduce` — самый выразительный из них. Он довольно запутан, поэтому не комплексуйте, если вам придётся попотеть.\n+\n+## Сужение возможностей\n+\n+После того, как представлен тип переменной, возникает любопытное свойство называемое *параметричностью*[^http://en.wikipedia.org/wiki/Parametricity]. Это свойство говорит, что функция будет *вести себя со всеми типами одинаково*. Давайте рассмотрим:\n+\n+```js\n+// head :: [a] -> a\n+```\n+\n+Вглядываясь в `head` мы видим как он превращает `[a]` в `a`. Кроме конкретнного типа `array`, не доступно больше никакой информации, следовательно, функциональность ограничена работой только над массивом. Что вообще можно сделать с переменной `a`, если ничего про нее не известно? `a` не говорит о том, что он какого-то *специфичного* типа, напротив, `a` может быть *любого* типа, что оставляет нам функцию, которая должна работать одинаково для *каждого* возможного типа. Это и есть *параметричность*. Задумываясь о реализации, единственно осмысленные допущения — это то, что функция вытаскивает первый, последний, или любой другой элемент из массива. Имя `head` должно подсказать нам, какой именно.\n+\n+Вот еще одна: \n+\n+```js\n+// reverse :: [a] -> [a]\n+```\n+\n+Исходя только из сигнатуры, чем может быть `reverse`? Вновь она не может сделать ничего особенного с `a`. Она не может привести `a` к какому-то другому типу. Может быть сортирует? Что же, нет, недостаточно информации, чтобы сортировать все  возможные типы. Возможно перетасовка? Да, я полагаю она может это сделать, но это должно происходить одинаковым и предсказуемым образом. Другая возможность, о которой я могу подумать, — это удаление или дублирование элемента. В любом случае, суть в том, что возможное поведение функции значительно сужается благодаря разнородности типа.\n+\n+Это сужение возможностей позволяет нам использовать сигнатуры типов в поисковых движках вроде [Hoogle](https://www.haskell.org/hoogle), чтобы найти функцию. Информация упакованная в сигнатуры — действительно довольно мощное средство.\n+\n+## Свобода в правилах\n+\n+Кроме вывода реализации возможностей, этот тип рассужденией дает нам *правила-теоремы, без дополнительных усилий*. Вот несколько случайных примеров прямиком из [работы Уодлера по этой теме](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf).\n+\n+```js\n+// head :: [a] -> a\n+compose(f, head) == compose(head, map(f));\n+\n+// filter :: (a -> Bool) -> [a] -> [a]\n+compose(map(f), filter(compose(p, f))) == compose(filter(p), map(f));\n+```\n+\n+Вам не нужен какой-либо код, чтобы получить эти правила, они следуют прямо из типов. Первое говорит нам, что если мы имеет `head` для массива, затем применяем некую функцию `f` к ней, то это эквивалентно (и между прочим, намного быстрее) тому, как если бы мы сначала исполнили `map(f)` на кажом элементе массива, а затем бы применили `head` к результату.\n+\n+Возможно вы думаете, ладно, это всего-лишь здравый смысл. Но в последний раз, когда я проверял, у компьютеров не было здравого смысла. Действительно, они должны иметь формальный способ автоматизировать подобные оптимизации программы. У математики есть средство, чтобы формализовать ход своих мыслей, что помогает продираться свозь жесткую местность компьютерной логики.","path":"ch7-ru.md","position":161,"original_position":161,"commit_id":"a954cf6c360d6cf425573f8e09d4ae1ec7417c69","original_commit_id":"a954cf6c360d6cf425573f8e09d4ae1ec7417c69","user":{"login":"maksimf","id":860283,"avatar_url":"https://avatars.githubusercontent.com/u/860283?v=3","gravatar_id":"","url":"https://api.github.com/users/maksimf","html_url":"https://github.com/maksimf","followers_url":"https://api.github.com/users/maksimf/followers","following_url":"https://api.github.com/users/maksimf/following{/other_user}","gists_url":"https://api.github.com/users/maksimf/gists{/gist_id}","starred_url":"https://api.github.com/users/maksimf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/maksimf/subscriptions","organizations_url":"https://api.github.com/users/maksimf/orgs","repos_url":"https://api.github.com/users/maksimf/repos","events_url":"https://api.github.com/users/maksimf/events{/privacy}","received_events_url":"https://api.github.com/users/maksimf/received_events","type":"User","site_admin":false},"body":"«Но в последний раз, когда я проверял, у компьютеров не было здравого смысла» → «Но, в последний раз когда я проверял, у компьютеров не было здравого смысла»","created_at":"2016-02-18T14:24:06Z","updated_at":"2016-02-18T14:24:06Z","html_url":"https://github.com/MostlyAdequate/mostly-adequate-guide-ru/pull/17#discussion_r53319317","pull_request_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/17","_links":{"self":{"href":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/comments/53319317"},"html":{"href":"https://github.com/MostlyAdequate/mostly-adequate-guide-ru/pull/17#discussion_r53319317"},"pull_request":{"href":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/17"}}},"pull_request":{"url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/17","id":58002133,"html_url":"https://github.com/MostlyAdequate/mostly-adequate-guide-ru/pull/17","diff_url":"https://github.com/MostlyAdequate/mostly-adequate-guide-ru/pull/17.diff","patch_url":"https://github.com/MostlyAdequate/mostly-adequate-guide-ru/pull/17.patch","issue_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/issues/17","number":17,"state":"open","locked":false,"title":"Сhapter 7","user":{"login":"zefirka","id":5380542,"avatar_url":"https://avatars.githubusercontent.com/u/5380542?v=3","gravatar_id":"","url":"https://api.github.com/users/zefirka","html_url":"https://github.com/zefirka","followers_url":"https://api.github.com/users/zefirka/followers","following_url":"https://api.github.com/users/zefirka/following{/other_user}","gists_url":"https://api.github.com/users/zefirka/gists{/gist_id}","starred_url":"https://api.github.com/users/zefirka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zefirka/subscriptions","organizations_url":"https://api.github.com/users/zefirka/orgs","repos_url":"https://api.github.com/users/zefirka/repos","events_url":"https://api.github.com/users/zefirka/events{/privacy}","received_events_url":"https://api.github.com/users/zefirka/received_events","type":"User","site_admin":false},"body":"Opening this PR to take your comments about style of translation. I was pretty careless with original text to avoid loan translation. If you'll accept this style, I will continue to translate 7th chapter. \r\n\r\nDiscuss? ","created_at":"2016-02-02T15:27:52Z","updated_at":"2016-02-18T14:24:06Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a70ff6b5d42403f9ebcdcc87e709858bf4461378","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/17/commits","review_comments_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/17/comments","review_comment_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/comments{/number}","comments_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/issues/17/comments","statuses_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/statuses/a954cf6c360d6cf425573f8e09d4ae1ec7417c69","head":{"label":"zefirka:chapter-7","ref":"chapter-7","sha":"a954cf6c360d6cf425573f8e09d4ae1ec7417c69","user":{"login":"zefirka","id":5380542,"avatar_url":"https://avatars.githubusercontent.com/u/5380542?v=3","gravatar_id":"","url":"https://api.github.com/users/zefirka","html_url":"https://github.com/zefirka","followers_url":"https://api.github.com/users/zefirka/followers","following_url":"https://api.github.com/users/zefirka/following{/other_user}","gists_url":"https://api.github.com/users/zefirka/gists{/gist_id}","starred_url":"https://api.github.com/users/zefirka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zefirka/subscriptions","organizations_url":"https://api.github.com/users/zefirka/orgs","repos_url":"https://api.github.com/users/zefirka/repos","events_url":"https://api.github.com/users/zefirka/events{/privacy}","received_events_url":"https://api.github.com/users/zefirka/received_events","type":"User","site_admin":false},"repo":{"id":48798956,"name":"mostly-adequate-guide-ru","full_name":"zefirka/mostly-adequate-guide-ru","owner":{"login":"zefirka","id":5380542,"avatar_url":"https://avatars.githubusercontent.com/u/5380542?v=3","gravatar_id":"","url":"https://api.github.com/users/zefirka","html_url":"https://github.com/zefirka","followers_url":"https://api.github.com/users/zefirka/followers","following_url":"https://api.github.com/users/zefirka/following{/other_user}","gists_url":"https://api.github.com/users/zefirka/gists{/gist_id}","starred_url":"https://api.github.com/users/zefirka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zefirka/subscriptions","organizations_url":"https://api.github.com/users/zefirka/orgs","repos_url":"https://api.github.com/users/zefirka/repos","events_url":"https://api.github.com/users/zefirka/events{/privacy}","received_events_url":"https://api.github.com/users/zefirka/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/zefirka/mostly-adequate-guide-ru","description":"Mostly adequate guide to FP (in javascript, translated in russian)","fork":true,"url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru","forks_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/forks","keys_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/teams","hooks_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/hooks","issue_events_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/issues/events{/number}","events_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/events","assignees_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/assignees{/user}","branches_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/branches{/branch}","tags_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/tags","blobs_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/git/refs{/sha}","trees_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/statuses/{sha}","languages_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/languages","stargazers_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/stargazers","contributors_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/contributors","subscribers_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/subscribers","subscription_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/subscription","commits_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/commits{/sha}","git_commits_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/git/commits{/sha}","comments_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/comments{/number}","issue_comment_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/issues/comments{/number}","contents_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/contents/{+path}","compare_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/merges","archive_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/downloads","issues_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/issues{/number}","pulls_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/pulls{/number}","milestones_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/milestones{/number}","notifications_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/labels{/name}","releases_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/releases{/id}","deployments_url":"https://api.github.com/repos/zefirka/mostly-adequate-guide-ru/deployments","created_at":"2015-12-30T12:07:10Z","updated_at":"2015-12-30T12:07:11Z","pushed_at":"2016-02-16T15:18:01Z","git_url":"git://github.com/zefirka/mostly-adequate-guide-ru.git","ssh_url":"git@github.com:zefirka/mostly-adequate-guide-ru.git","clone_url":"https://github.com/zefirka/mostly-adequate-guide-ru.git","svn_url":"https://github.com/zefirka/mostly-adequate-guide-ru","homepage":null,"size":3937,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"MostlyAdequate:master","ref":"master","sha":"c9e4a38760aedfef9917e10b5accfa9ee95f4663","user":{"login":"MostlyAdequate","id":14079115,"avatar_url":"https://avatars.githubusercontent.com/u/14079115?v=3","gravatar_id":"","url":"https://api.github.com/users/MostlyAdequate","html_url":"https://github.com/MostlyAdequate","followers_url":"https://api.github.com/users/MostlyAdequate/followers","following_url":"https://api.github.com/users/MostlyAdequate/following{/other_user}","gists_url":"https://api.github.com/users/MostlyAdequate/gists{/gist_id}","starred_url":"https://api.github.com/users/MostlyAdequate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MostlyAdequate/subscriptions","organizations_url":"https://api.github.com/users/MostlyAdequate/orgs","repos_url":"https://api.github.com/users/MostlyAdequate/repos","events_url":"https://api.github.com/users/MostlyAdequate/events{/privacy}","received_events_url":"https://api.github.com/users/MostlyAdequate/received_events","type":"Organization","site_admin":false},"repo":{"id":41765171,"name":"mostly-adequate-guide-ru","full_name":"MostlyAdequate/mostly-adequate-guide-ru","owner":{"login":"MostlyAdequate","id":14079115,"avatar_url":"https://avatars.githubusercontent.com/u/14079115?v=3","gravatar_id":"","url":"https://api.github.com/users/MostlyAdequate","html_url":"https://github.com/MostlyAdequate","followers_url":"https://api.github.com/users/MostlyAdequate/followers","following_url":"https://api.github.com/users/MostlyAdequate/following{/other_user}","gists_url":"https://api.github.com/users/MostlyAdequate/gists{/gist_id}","starred_url":"https://api.github.com/users/MostlyAdequate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MostlyAdequate/subscriptions","organizations_url":"https://api.github.com/users/MostlyAdequate/orgs","repos_url":"https://api.github.com/users/MostlyAdequate/repos","events_url":"https://api.github.com/users/MostlyAdequate/events{/privacy}","received_events_url":"https://api.github.com/users/MostlyAdequate/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/MostlyAdequate/mostly-adequate-guide-ru","description":"Mostly adequate guide to FP (in javascript, translated in russian)","fork":false,"url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru","forks_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/forks","keys_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/teams","hooks_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/hooks","issue_events_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/issues/events{/number}","events_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/events","assignees_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/assignees{/user}","branches_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/branches{/branch}","tags_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/tags","blobs_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/git/refs{/sha}","trees_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/statuses/{sha}","languages_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/languages","stargazers_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/stargazers","contributors_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/contributors","subscribers_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/subscribers","subscription_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/subscription","commits_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/commits{/sha}","git_commits_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/git/commits{/sha}","comments_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/comments{/number}","issue_comment_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/issues/comments{/number}","contents_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/contents/{+path}","compare_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/merges","archive_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/downloads","issues_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/issues{/number}","pulls_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls{/number}","milestones_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/milestones{/number}","notifications_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/labels{/name}","releases_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/releases{/id}","deployments_url":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/deployments","created_at":"2015-09-01T21:47:19Z","updated_at":"2016-02-17T22:08:12Z","pushed_at":"2016-02-16T15:18:02Z","git_url":"git://github.com/MostlyAdequate/mostly-adequate-guide-ru.git","ssh_url":"git@github.com:MostlyAdequate/mostly-adequate-guide-ru.git","clone_url":"https://github.com/MostlyAdequate/mostly-adequate-guide-ru.git","svn_url":"https://github.com/MostlyAdequate/mostly-adequate-guide-ru","homepage":null,"size":3932,"stargazers_count":57,"watchers_count":57,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":14,"mirror_url":null,"open_issues_count":3,"forks":14,"open_issues":3,"watchers":57,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/17"},"html":{"href":"https://github.com/MostlyAdequate/mostly-adequate-guide-ru/pull/17"},"issue":{"href":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/issues/17"},"comments":{"href":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/issues/17/comments"},"review_comments":{"href":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/17/comments"},"review_comment":{"href":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/pulls/17/commits"},"statuses":{"href":"https://api.github.com/repos/MostlyAdequate/mostly-adequate-guide-ru/statuses/a954cf6c360d6cf425573f8e09d4ae1ec7417c69"}}}}