
В этот раз мы рассмотрим операции своеобразного «деления функторов». Начнём с обобщения задачи поиска сопряжённых функторов, но потом убедимся, что расширения Кана являются фундаментальной абстракцией, лежащей в основе множества полезных инструментов.
Поверхностный обзор расширений Кана получился весьма объёмным, поэтому в эту статью не вошла техника получения этих конструкций. По той же причине здесь (почти) не упоминается scala-код. Пришлось оставить эти темы на следующий раз.
Оглавление обзора
Расширения Кана (данная публикация)
Исчисление концов
Построение монад
Содержание
Определения и свойства
Примеры расширений Кана
Коплотность и передача продолжений
Свободная монада
Определение и свойства
Правые расширения Кана
Пусть у нас есть функтор и нам нужно найти для него такой
, чтобы существовало сопряжение
с естественными преобразованиями
Функтор выглядит обратным к
в том смысле, что их композиция позволяет получить тождественный функтор
, играющий роль «единицы» для операции композиции, напоминающей «произведение» функторов. Поэтому для
встречается другое обозначение:
, что делает сопряжение чуть более наглядным:
Конечно же, имеется в виду не привычное деление, которое могло бы получиться, если бы здесь были строгие равенства и операция \circ коммутировала. Сейчас это просто обозначение, в котором искомый функтор сформулирован через два известных, участвующих в естественных преобразованиях сопряжения. Но оно толсто намекает на обобщение, получаемое, если в коединице сопряжения заменить тождественный функтор на произвольный , определённый на той же категории, что и
:

Правым расширением Кана функтора вдоль функ��ора
называется такой функтор
вместе с естественным преобразованием
, что для любого кандидата
с преобразованием
существует единственное преобразование
, такое что
.
Обозначение происходит от «Right Kan Extension», а преобразование
называют коединицей правого расширения Кана. Вертикальная
и горизонтальная
композиции естественных преобразований были представлены в обзоре ранее.
Как же можно «расширить» один функтор «вдоль» другого? У математиков вообще очень своеобразное воображение. Но давайте всё же попробуем их хоть немного понять и простить.
Перерисуем предыдущую категориальную диаграмму в таком виде:

Функторы и
отображают категорию
в
и
. Само это отображение уже как бы «сопоставляет» между собой образы функторов, подкатегории
и
. Задача функтора
— продемонстрировать это сопоставление, «расширив» его с образа
на всю категорию
так, чтобы естественное преобразование
явно переводило объекты из
в
. Получается, что подкатегория
как бы «расширяется» до
, внутри которой есть подкатегория
, явно сопоставленная с
преобразованием
… Ну всё же очевидно, да? Впрочем, неважно — главное, что математики делают вид, что такое название вполне соответствует сути.
Свойства правого расширения Кана
Запись правого расширения Кана через инфиксный оператор отражает своего рода «обратность» этой конструкции по отношению к композиции функторов, аналогично делению по отношению к умножению. В частности, для композиции расширений Кана
справедлива привычная алгебраическая формула:
Обозначение является более стандартным. В этом случае
сам выступает в роли функтора, действующего между категориями функторов. Если
, то для любой категории
получаем
. Любопытно, что этот функтор оказывается сопряжённым справа к фун��тору предкомпозиции функторов
(где прочерк обозначает место для аргумента-функтора):
Действительно, для любого выпоняется следующий изоморфизм:
Слева здесь морфизмы в категории функторов — совокупность естественных преобразований
, каждое из которых вместе с функтором
образует кандидата в правое расширение Кана. Справа же — универсальный морфизм
для этого кандидата. Изоморфизм просто говорит о том, что каждому кандидату взаимно однозначно соответствует единственный универсальный морфизм. Коединица такого сопряжения
соответствует коединице расширения Кана, а единица имеет вид
.
Ранее в предыдущей части обзора мы разбирали сопряжение эндофункторов в категории типов Writer[S] ⊣ Reader[S]. Любопытно, что для него получается внешне похожий hom-изоморфизм: . Произведение объектов аналогично (с некоторой натяжкой) композиции функторов, но если первой операции противопоставляется экспоненциал, то во втором случае мы получили что-то вроде деления! Как могут быть связаны экспоненциал и деление?
Эту связь проще понять, сравнив алгебраическое равенство и функцию оценки
. В обоих случаях справа имеем
, а слева — произведения чего-то на
. Если в одном случае в произведении присутствует дробь
, то во втором — экспоненциал
, который является решением задачи «что в сочетании с
позволяет получить
?». Такое неожиданное сопоставление «деления» с «экспоненциалом» обусловлено тем, что в теории категорий так или иначе все вычисления сводятся к манипулированию hom-объектами (в теории типов — функциями). Мы ещё увидим это в следующей части обзора.
Левые расширения Кана
Мы пришли к правому расширению Кана, обобщив задачу поиска левого сопряжения (как ни парадоксально)). Если же бы мы начали с поиска правого расширения, то, ожидаемо, получили бы левое расширение Кана:

Левым расширением Кана функтора вдоль функтора
называется такой функтор
вместе с естественным преобразованием
, что для любого кандидата
с преобразованием
существует единственное преобразование
, такое что
.
Обозначение \mathrm{Lan} происходит от «Left Kan Extension», а преобразование называют единицей левого расширения Кана.
В данном обзоре наравне с общепринятым будет использоваться нестандартное обозначение . Функтор, который мы факторизуем, располагается как бы над чертой, а через который факторизуем — под ней. Такое обозначение «левого деления функторов» отражает дуализм по отношению к «правому делению»
.
По аналогии с , универсальное свойство для
образует похожее сопряжение с функтором предкомпозиции, что даёт сопряжённую тройку:
Для левых расширений Кана работает похожее правило композиции: , или в других обозначениях
Подъёмы Кана
Расширения Кана строятся для функторов, исходящих из одной категории. Но можно пойти и другим путём — рассматривать функторы, сходящиеся в одну и ту же категорию. Тогда получатся ещё два способа факторизации одного функтора по другому. Эти конструкции называются подъёмами Кана и
. В отличие от расширений Кана, они образуют сопряжённую тройку вокруг посткомпозиции:
Подъёмы Кана обладают свойствами, аналогичными расширениям, и они имеют те же основания называться «делением функторов». Так что в сумме мы имеем целых четыре различные операции, «обратные» композиции функторов. И это одна из причин, почему инфиксный оператор / не часто используется в качестве обозначения правого расширения Кана.
Тем не менее, расширений Кана вполне достаточно для решения большинства задач и подъёмы Кана практически нигде не рассматриваются.
Давайте теперь посмотрим на конкретные примеры как левых, так и правых расширений Кана.
Примеры расширений Кана
Сопряжения

Ранее уже были намёки, но теперь скажем прямо: если для функтора существуют левое/правое сопряжение, то это будут (с точностью до изоморфизма) правое/левое расширение Кана тождественного функтора
вдоль
:
В предыдущей части обзора было показано, как сопряжённые тройки порождают монады и комонады. Представленная тройка интересна тем, что она параметризована единственным функтором — он один порождает целую россыпь (ко)монад:
монады:
и
;
комонады:
и
.
(Ко)пределы
Давайте вспомним, как устроены (ко)пределы функторов. Для некоторого (не для каждого) функтора существуют такие объекты
, которые в некотором смысле наилучшим образом представляют этот самый функтор. Такой объект, вместе с семейством морфизмов, индексированных объектами
, образуют универсальный (ко)конус — естественное преобразование между заданным функтором
и константным
.
Константный функтор сочетает в себе две операции — полное «забывание» всей структуры категории
и выбор конкретного объекта
. Удобно факторизовать диагональный функтор на два вспомогательных — один будет отвечать за «схлопывание» исходной категории в категорию
, состоящую из единственного объекта и его тождественного морфизма, а другой функтор будет отображать
в
, выбирая там нужный объект
:
Категория является терминальным объектом в категории категорий. Функтор
является его универсальным морфизмом, единственным образом «забывающим» структуру исходной категории, переводя все её морфизмы в тождественный для единственного объекта. Эта ситуация аналогична той, что мы рассматривали раньше в категории типов — тип
Unit является её терминальным объектом, так как существует единственный способ (функция) привести к нему любой другой тип.
Любой функтор, исходящий из , моделирует её в целевой категории
, то есть, по сути, выбирает из неё единственный объект. Категория таких функторов
изоморфна дискретной подкатегории, построенной на тех же объектах, что и
. Поэтому часто для простоты эти функторы обозначают также, как и объекты
.
Получается следующая диаграмма в категории категорий:

Функтор факторизуется через
посредством «наилучших»
и
, что отсылает нас к расширениям Кана.
Действительно, несложно убедиться, что
Другими словами, если (ко)предел функтора существует, то соответствующий «выбирающий функтор» будет изоморфен левому/правому расширению Кана
вдоль
.
Представления Йонеды

Ранее мы видели расширения функтора F вдоль себя и тождественного вдоль F. Для полноты картины рассмотрим расширение функтора вдоль тождественного.
Эти расширения Кана соответствуют так называемым представлениям Йонеды:
Трудности перевода
Японский математик Нобуо Йонеда (написание через «йо» уже устоялось) доказал в теории категорий очень важную лемму, и мы ещё рассмотрим её позднее. Саундерс Маклейн, один из основателей теории категорий, предложил назвать эту лемму именем автора. То же имя получили специфичный для леммы функтор (вложение Йонеды), а также рассмотренные выше представления функторов.
Для этих конструкций иногда используют обозначения или просто
, но в одной работе 2015 года предложили более короткое обозначение
— букву японской азбуки хирагана, читающуюся как «ё», первый слог фамилии Йонеды.
Японские фамилии обычно записывают иероглифами, которые могут иметь разное прочтение, и японцы пользуются хираганой, чтобы пояснять, как правильно читать их фамилии. Оригинальная запись фамилии Йонеды состоит из двух иероглифов: «米田», где «米» имеет самостоятельное значение «рис» и читается как [коме]. Поэтому использовать такой символ в качестве математического обозначения было бы не лучшей идеей.
Авторы той статьи обосновывали отказ от символа 米 как-то так: «в нём слишком много черт, и неудобно записывать на доске»… В данном же обзоре символ выбран ещё и потому, что его произношение «Ё» несёт особую энергетику, которая призвана помочь программистам в усвоении основ теории категорий)).
Кстати, обычно этот символ используют для вложения Йонеды, но здесь им обозначены именно представления Йонеды, так как они более важны в программировании.
Интересной особенностью представлений Йонеды является то, что они изоморфны исходным функторам:
Действительно, возьмём к примеру представление ко-Йонеды . Единица этого расширения Кана даёт одну ветвь изоморфизма
. Обратную ветвь мы получим как универсальный морфизм
, если в качестве кандидата выберем
с преобразованием
. Универсальный морфизм буквально является обратным к единице
и при этом он однозначно фиксирован выбором кандидата. Для представления Йонеды
результат будет аналогичным.
Казалось бы, какая может быть польза от изоморфных функторов? Секрет в том, что представления позволяют оптимизировать цепочки простых преобразований внутри «контейнера» . А именно, если последовательность морфизмов из категории
по шагам переносится представлением Йонеды функтора
в
, то, (внезапно!) сам функтор
при этом не задействуется! Представление
на каждом шаге комбинирует преобразования в одно действие, тогда как
запоминает их в своеобразном «списке». К сожалению, не нашёл способа продемонстрировать эту оптимизацию, не вникая в устройство представлений Йонеды и расширений Кана. Но мы обязательно сделаем это в продолжении обзора.
В обоих случаях реальное использование функтора происходит лишь в момент «распаковки» представления посредством изоморфизма. Наиболее принципиальное различие между представлениями заключается лишь в том, на каком этапе требуется предоставить доказательства функториальности
— при переходе к представлению, или при возвращении обратно.
Представление ко-Йонеды также часто называют свободным функтором. Дело в том, что в общем случае для отображения , переводящего морфизмы одной категории в другую, у нас могут отсутствовать «свидетельства» функториальности. Но даже в этом случае мы можем построить для
представление ко-Йонеды, которое будет полноценным функтором! Поэтому и говорят, что
является функтором, свободным от наличия функториальности самого
. Она может понадобиться лишь для «распаковки»
, но и тут зачастую есть возможность выкрутиться, если получится преобразовать
в какой-нибудь настоящий функтор
.
Коплотность и передача продолжений
Монада коплотности
Не для каждого функтора могут существовать левое и правое сопряжения. В таких случаях расширения Кана и
можно рассматривать как «наилучшие попытки» построить сопряжения. Если же для функтора
сопряжения существуют, то справедливыми оказываются следующие изоморфизмы:
Соотношения кажутся очевидными со школы, но ввиду не совсем обычных операций «деления функторов», можно считать, что они получились совершенно случайно)).
К примеру, рассмотрим первый изоморфизм, представленный двумя встречными естественными преобразованиями:
Они должны фиксироваться известными преобразованиями сопряжения, а также коединицей расширения Кана :
С их помощью одна ветвь изоморфизма выражается так:
А вот для явного выражения данных преобразований недостаточно. Тут нас выручит универсальный морфизм расширения Кана
, взаимно однозначно соответствующий преобразованию
, заданному для произвольного кандидата
. Выберем в качестве кандидата тождественный функтор
в категории
с тождественным преобразованием
. Для такого кандидата у нас будет универсальный морфизм вида
Он поможет нам явно выписать другую ветвь искомого изоморфизма:
Тут можно заметить подвох — утверждается, что у нас уже есть преобразование , однозначно фиксированное известными
и
через универсальное свойство. Однако
определяется как решение уравнения
, и для него просто нет явного выражения в виде композиции естественных преобразований! Мы, конечно, могли бы попробовать ввести что-то вроде операции «деления естественных преобразований», но тут используется другой подход, и мы рассмотрим его в другой раз. Пока же достаточно того, что нам удалось продемонстрировать корректность изоморфизма
.
Так зачем же нам заморачиваться с таким изоморфизмом и функтором ? Сопряжение даёт нам монаду для
, но фокус в том, что
образует монаду даже тогда, когда функтор
вообще не имеет левого сопряжения! Правое расширение Кана функтора
вдоль самого себя называется монадой коплотности функтора
:
Преобразования монады можно получить, воспользовавшись знакомым трюком, основанном на эксплуатации универсального свойства расширения Кана для конкретных кандидатов. Полученное ранее преобразование даёт «запаковку» для нашей монады. Если же в качестве кандидата выберем
с преобразованием
, то ему будет взаимно однозначно соответствовать универсальный морфизм
, по счастливой случайности отвечающий как раз за «разматрёшивание» монады.
Универсальное свойство монады коплотности обладает ещё одной замечательной особенностью. Дело в том, что в преобразовании для кандидатов вида
можно поменять левую ассоциативность композиции на правую:
Здесь учтено, что . Коединица
по сути отвечает за «распаковку» функтора
, а преобразование
является композицией таких распаковок.
Кандидату с таким преобразованием
соответствует универсальный морфизм
, отвечающий за многократное монадное «разматрёшивание». Его устройство мы изучим в другой раз, но, по аналогии с
, очевидно, что каждая его компонента — это просто композиция обычных
функций морфизмов! Универсальное свойство меняет лево-ассоциативную композицию, используемую при построении, на право-ассоциативную, оптимизированную для вычислений. Это позволяет разматрёшивать глубокую вложенность за один проход, просто применяя преобразования справа налево.
В программировании монада коплотности даёт мощную оптимизацию вычислений цепочек функций с эффектами. Она позволяет «схлопывать» произвольное количество вызовов flatMap в единую функциональную композицию, сохраняя при этом исходный контекст F[A]. Если F[_] — это тяжеловесная рекурсивная структура (будь то список, дерево SQL-запроса или свободная монада), коплотность превращает квадратичную сложность выполнения n преобразований в линейную
, делая доступ к каждому следующему шагу вычисления мгновенным
.

Аналогично доказывается изоморфизм . Левое расширение Кана функтора
вдоль самого себя образует комонаду плотности
, и её существование не зависит от наличия правого сопряжения к
.
(Ко)монады в категории , порождённые сопряжённой тройкой, построенной вокруг функтора
, также иногда описывают с позиции «плотности»:
Они имеют больше отношения к упомянутым ранее подъёмами Кана, и упоминаются редко.
Про «плотность»
Концепция плотности позаимствована из топологии. Считается, что множество плотно в
(как рациональные числа в вещественных), если любая точка
является пределом последовательности из
. Теория категорий обобщает это понятие: функтор
называется (ко)плотным, если для каждого
в образе
найдётся такая диаграмма, что
будет её (ко)пределом.
Для плотного функтора выполняется условие
, а для коплотного —
. Если эти расширения Кана не изоморфны тождественному эндофунктору, значит функтор
отображает исходную категорию «не (ко)плотно» — либо в исходной категории не достаточно данных, либо сам функтор слишком «забывчивый». Плотные функторы позволяют «воссоздать» из своего образа все объекты категории
.
Коплотные функторы содержат в своём образе достаточно диаграмм, чтобы «детектировать» все объекты в , различить их только на основе морфизмов из образа.
И плотные, и коплотные функторы отвечают за своеобразное «кодирование» целой категории лишь малой её частью, но делают они это по-разному, дуально. Естественно, большинство функторов не обладают ни тем, ни другим свойством, но есть и такие, которые являются и плотными и коплотными одновременно. Например, это изоморфизмы категорий, или отображения в скелет категории (содержащий лишь по одному объекту для каждого изоморфизма в категории).
Монада передачи продолжений
Итак, представление Йонеды позволяет оптимизировать цепочку чистых вычислений под функтором, тогда как монада коплотности специализируется на оптимизации вычислений с эффектами. Оказывается, мы можем объединить эти оптимизации, построив монаду передачи продолжений:
Полученная монада изоморфна коплотности , но именно в этом виде она более оптимизирована. Для обратного преобразования
в
требуется передать функцию с эффектом
, продолжающую вычисления с «запакованным» значением (мы увидим, как это работает, в продолжении обзора). Отсюда и происходит название монады.
Данная конструкция лежит в основе особой техники программирования — стиля передачи продолжений (Continuation Passing Style). Эта техника встроена в компиляторы многих языков программирования и применяется в различных библиотеках Scala, в том числе в новомодном «direct style», активно продвигаемом Мартином Одерски.
Свободная монада
Формулировка через левое расширение Кана
Само устройство свободной монады функтора мы рассмотрим в продолжении обзора. Сейчас просто примем, что она выражается через левое расширение Кана
где — забывающий функтор из категории F-алгебр. Объектами этой категории являются пары
, а морфизмы между
и
представляют собой функции
, такие что
(гомоморфизмы алгебр функтора). Действие забывающего функтора
на морфизмы тривиально, а из объектов он просто выбрасывает второй элемент пары. Поэтому можно считать, что для любого
автоматически задан такой забывающий функтор.
Тут стоит отметить два очень важных факта.
Во-первых, категория алгебр функтора сильно отличается от категории алгебр монады, рассмотренной ранее в обзоре. В первой меньше ограничений, а значит, больше объектов и морфизмов. Мы разберём этот нюанс подробнее в другой раз, но сейчас важно просто не спутать эти категории.
Во-вторых, как мы уже видели раньше, левое расширение Кана образует комонаду плотности забывающего функтора
. Но магическим образом оно же является и свободной монадой для эндофунктора
!
В отличие от монады коплотности, здесь мы не получаем изоморфизма с исходным функтором: . Однако универсальное свойство расширения Кана даёт нам естественное преобразование
и преобразование морфизмов
, которое позволяет строить монадические композиции F-эффективных функций для абсолютно любого функтора
:
Функция является программой, составленной из F-эффектных шагов, «поднятых в мир Free». Исполнение такой программы осуществляется с помощью преобразования
для заданной монады
с дальнейшей «распаковкой» этой монады.
Другие представления
Существуют и другие представления свободной монады. Например, её можно выразить в виде копредела функтора (
— натуральные числа, включающие
). Но сейчас мы не будем погружаться в эти детали. Достаточно только иметь в виду, что копредел также выражается через левое расширение Кана и свободная монада в таком представлении выглядит так:
.
Более свободная монада
Свободная монада эндофунктора «освобождает» нас от необходимости предоставлять монадные преобразования для этого функтора. Ранее же мы видели, что представление ко-Йонеды «освобождает» нас даже от функториальности
. Естественно, мы можем объединить две эти конструкции, получив более свободную монаду:
где — забывающий функтор из категории алгебр уже для
.
Более свободная монада позволяет строить пути вычислений из шагов вида даже если
не является функтором (нет свидетельства функториальности)! Выполнение вычислений производится с помощью такого же
(только преобразования от «не-функтора»
уже не могут называться «естественными»).
Перечисленные особенности лежат в основе специальной техники программирования, собирающей «программу-как-данные» из абстрактных контейнеров (GADT), описывающих бизнес-операции. В конце такая программа «сворачивается» с использованием интерпретаторов этих контейнеров в какой-нибудь IO.
Оптимизированная свободная монада
И конечно же, свободную монаду можно оптимизировать, обернув её в монаду продолжения:
Эта идея стала популярной благодаря работам Олега Киселёва:
Reflection without Remorse (2014),
В языке Scala оптимизированная свободная монада реализована в нескольких библиотеках, но немного по-разному.
В библиотеке Scalaz монада продолжений реализована явно, но тип
Free[F[_], A]воплощает конструкциюдля существующих функторов (оптимизация продолжениями обеспечивается слагаемым
Gosub <: Free). Если нужно «освободить не-функтор», то для этого используется типFreeC[F[_], A], в точности соответствующий определённому выше.
В библиотеке Cats представлен аналогичный тип
Free[F[_], A], который ближе к простому. Но «под капотом» шаги преобразований переассоциируются методом
stepвнутриfoldMap(илиrun), что и отсылает к монаде продолжений.В библиотеке Eff реализованы основные идеи Киселёва. Контейнер
Eff[FT, A]устроен сложнее, чем обычная свободная монада (FTявляется неким значком, соответствующим композиции различныхF[_]), и это даёт очень интересные возможности по комбинированию эффектов. Но концептуально, это воплощение всё того же.
Также в библиотеках встречается контейнер
Eval[_], который представляет собой свободную монаду, построенную над Id.
Таким образом, конструкции Free, которые современные библиотеки предоставляют в качестве свободной монады, реализуют сложную абстракцию, собранную из множества расширений Кана.
Монадный трансформер коплотности
Пусть у нас есть монада и функтор
. Давайте рассмотрим такое расширение Кана:
. Его коединицей будет
. Оказывается, что
образует новую монаду
.

Её естественные преобразования, а также специальная операция «подъёма» однозначно фиксируются следующими уравнениями, получаемыми благодаря универсальным морфизмам
для разных кандидатов
:
Такое расширение Кана трансформирует монаду T вдоль функтора F из категории в
!
Стоп, не всё так просто. Монада получается вовсе не для любых и
. Существуют такие частные случаи
, при которых мы получим монаду для любого
, но это не особо интересно. Самое важное ограничение накладывается на функтор
— для него должен существовать лево сопряжённый
, тогда мы сможем трансформировать вдоль него любую монаду
. По этой причине часто говорят о построении монадного трансформера (устоявшееся название) вдоль функтора
:
Конечно же, здесь подразумевается не только трансформация самих эндофункторов, но и естественных преобразований соответствующих монад.
В программировании мы обычно имеем дело с эндофункторами в одной и той же категории типов , так что монадные трансформеры иногда рассматриваются как легальный способ композиции монад. Благодаря «подъёму»
и «спуску»
, расширение Кана
порождает монаду, которую часто ассоциируют именно с композицией
. Но в данном случае речь идёт скорее не о композиции, а об «индуцировании» новой монады из исходной
. Если у эндофунктора
есть свои монадные возможности, то они не задействуются, а вместо них срабатывает механика коплотности.
Важный момент: обычно программисты имеют дело с трансформерами вида FT[G, ], соответствующими функторам G[F[]]. Такой трансформер жёстко привязан к структуре внутренней монады композиции. В Scala-библиотеках представлены скромные наборы таких трансформеров для наиболее востребованных монад, но нет способов построить универсальный трансформер, работающий для любой внутренней монады F.
Полученный здесь монадный трансформер коплотности работает иначе. В отличие от привычных трансформеров, он надстраивается над внешним функтором композиции
. Кроме того, в программировании устраняется неудобное ограничение расширения Кана. В декартово замкнутой категории типов присутствуют типы любых функций. Расширения Кана здесь будут не просто поточечными, но сильными, что выражается в программировании посредством полиморфных функций высокого порядка. Это снимает ограничение на представимость функтора
(на наличие левого сопряжения), что позволяет строить монады действительно для любых
и
!
Дополнительно, структура коплотности даёт рассмотренную ранее оптимизацию цепочки вычислений в контексте этой монады.
Дополнительная литература
Публикации из блога Comonads Эдварда Кметта
Публикации из блога String Diagrams Дэна Марсдена:
Статья Тома Лейнстера The Yoneda Lemma: What's It All About (pdf)
Промежуточный итог
Композицию функторов часто ассоциируют с понятием «умножения», а расширения Кана иногда трактуют как своеобразные операции «деления функторов». Именно по этой причине в данной публикации чаще используются обозначения расширений Кана в виде дробей. Но важно понимать, что, в отличие от школьной алгебры, здесь «умножение» не перестановочно, а «дроби» далеко не всегда удаётся упростить. И вообще, мы имеем не одну, а сразу две обратные операции — левое и правое
расширения Кана (плюс ещё пара редко используемых подъёмов Кана).
Расширения Кана дополняют операцию композиции функторов, что позволяет решать обратные задачи — вычислять функторы, удовлетворяющие заданным композиционным уравнениям. Подобные уравнения возникают, например, когда требуется вычислить (ко)предел функтора, или же его левое/правое сопряжение.
Большое значение имеют конструкции (ко)Йонеды и (ко)плотности. Первые представляют собой расширения заданного функтора вдоль Id, а вторые — вдоль самого себя. Эти конструкции позволяют оптимизировать некоторые вычисления и даже построить (ко)монады для произвольного функтора.
Кроме того, расширения Кана дают возможность трансформировать существующие (ко)монады вдоль заданного функтора. Получаемый таким способом монадный трансформер коплотности может быть полезен в качестве инструмента для построения композиции произвольных монад.
Расширения Кана представляют собой фундаментальные абстракции, через которые выражается множество других конструкций, применяемых в том числе и в программировании. Но реальная практическая ценность заключается в том, что для расширения Кана разработана специальная техника их вычисления. Этой теме и будет посвящена следующая часть обзора.
