29 ноября 2011 в 10:46

Эндофункторы категории Hask и их моноидальная структура

Введение


В предыдущей статье я рассказал о понятиях категории и функтора в контексте категории Hask, состоящей из типов данных и функций языка Haskell. Теперь я хочу рассказать о другом примере категории, построенном из уже известных нам понятий, а так же о весьма важном понятии моноида.

Обозначения


В прошлый раз я хотел обозначить морфизм/функцию буквой f, но она была занята для обозначения функтора/переменной типа f – никакой проблемы с точки зрения языка Haskell в этом нет, но при невнимательном прочтении это может вызвать путаницу, и я использовал для морфизма букву g. Пустяк, но всё же, я считаю, что полезно визуально разделять сущности, имеющие разную природу. Обычные типы я буду называть их обычными именами, а вот переменные типов я буду называть маленькими греческими буквами, причём простые () – буквами из начала алфавита, а параметрические (∗ → ∗) – буквами из конца алфавита (θ не из конца, но она смотрится лучше, чем χ, которая слишком похожа на X). Итак, в терминологии категории Hask:
  • Объекты: α, β, γ, δ ∷ ∗
  • Функторы: θ, φ, ψ, ω ∷ ∗ → ∗
  • Морфизмы: f, g, h ∷ α → β
Ввиду того, что GHC довольно давно поддерживает unicode, эти обозначения ничего не меняют в отношении синтаксиса и носят чисто косметический характер.

Ещё одно замечание, касательно терминологии: как вы уже заметили, то, что я в прошлый раз называл словом “кайнд” (kind), я теперь называю словом “сорт” – это считается общепринятым переводом.

Категория с объектом Hask


Давайте рассмотрим категорию, в которой будет только один объект – сама категория Hask. Что же будет морфизмами в такой категории? Это должны быть какие-то отображения HaskHask, и мы уже знаем такой тип отображений – это эндофункторы категории Hask, то есть типы сорта ∗ → ∗, воплощения класса Functor. Теперь нужно продумать как устроены единичный морфизм и композиция в этой категории, так чтобы они удовлетворяли аксиомам.

Тождественный функтор


В качестве единичного морфизма естественно выбрать тождественный функтор, то есть такой функтор, который ничего не меняет. В Haskell для него нет специального обозначения – раз он ничего не делает, зачем его как-то обозначать? Я введу “фиктивный” конструктор типа, с помощью которого можно будет “визуализировать” действие этого функтора на объектах категории Hask:
type Id α = α

В Haskell нельзя объявлять воплощения для синонимов типов, поэтому Id нельзя ввести полностью аналогично другим функторам, но если бы можно было, мы бы написали так:
-- warning: псевдо-код
instance Functor Id where
    fmap ∷ (α → β) → (Id α → Id β)
    fmap f = f
То есть поведение этого функтора на морфизмах определяется тривиально: fmap ≡ id ∷ (α → β) → (α → β) – тут конструктора Id нет, но это та же сигнатура. Итак, два отображения функтора выглядят так:
α ∷ ∗      ↦  Id α = α ∷ ∗
f ∷ α → β  ↦  id f = f ∷ α → β

Хотя этот функтор и кажется бесполезным, он нам необходим для полноты определения категории. Кроме того, он даёт возможность воспринимать любой тип α ∷ ∗ как Id α ∷ ∗, то есть под действием тождественного функтора – это ещё пригодится, когда мы встретимся с монадами.

Композиция функторов


В рассматриваемой нами категории теперь не хватает только композиции морфизмов (эндофункторов). Поскольку мы рассматриваем морфизмы на одном объекте, они все имеют одинаковую область и кообласть, так что мы априори знаем, что композиция применима к любым двум морфизмам.

Начнём с примера. Рассмотрим два известных нам функтора: Maybe и []. Вот как они действуют на объектах:
α ∷ ∗  ↦  Maybe α ∷ ∗
β ∷ ∗  ↦  [β] ∷ ∗

Композиция означает, что мы сначала применяем одно отображение, а к тому что получилось – второе:
α  ↦  Maybe α  ↦  [Maybe α]
Или в другом порядке:
α  ↦  [α]  ↦  Maybe [α]
Для того, чтобы применять композицию к конструкторам типов, ничего особенного не нужно – просто пишем сначала один, потом другой. Введём для этой операции обозначение, похожее на обычную композицию (конструктор типа в виде оператора должен начинаться с двоеточия, а второе я ставлю просто для симметрии):
type (φ :.: ψ) α = φ (ψ α)

Теперь посмотрим, что с отображением морфизмов. Поскольку у любого функтора это отображение имеет имя fmap, можно сказать в общем, что нужно применить к морфизму сначала один fmap, а потом второй, то есть отображение композиции функторов будет таким: λf → fmap (fmap f) или просто fmap . fmap. Нужно понимать, что эти два fmap – разные ипостаси одной полиморфной функции – у каждой свой тип и соответствующее ему определение. Продемонстрируем это наглядно:
instance Functor Maybe where
 -- fmap ∷ (α → β) → (Maybe α → Maybe β)
    fmap f = f'
       where f' Nothing  = Nothing
             f' (Just x) = Just (f x)

instance Functor [] where
 -- fmap ∷ (α → β) → ([α] → [β])
    fmap g = g'
       where g'   []   = []
             g' (x:xs) = (g x) : (g' xs)

Теперь рассмотрим композицию на примере: [] :.: Maybe
(fmap . fmap) ∷ (α → β) → ([Maybe α] → [Maybe β])

(fmap . fmap) even [Just 2, Nothing, Just 3] ≡ 
                [Just True, Nothing, Just False]

И в другом порядке: Maybe :.: []
(fmap . fmap) ∷ (α → β) → (Maybe [α] → Maybe [β])

(fmap . fmap) even Just [1, 2, 3] ≡ Just [False, True, False]
(fmap . fmap) even Nothing ≡ Nothing

Если бы мы хотели сделать композицию функторов воплощением класса Functor, то сделали бы это примерно так, как делают авторы пакета TypeCompose. Я впрочем не вижу в этом особого смысла, поскольку приходится оборачивать значения в дополнительный конструктор данных. Итак, если говорить о функторах, как о парах отображений (на объектах и морфизмах), то для двух функторов (φ, fmapφ) и (ψ, fmapψ), их композицией будет такая пара отображений: (φ :.: ψ, fmapφ . fmapψ), то есть

α ∷ ∗ ↦ (φ :.: ψ) α ∷ ∗
f ∷ α → β ↦ (fmapφ . fmapψ) f ∷ (φ :.: ψ) α → (φ :.: ψ) β

Формально, нужно проверить, что эта пара отображений сама является эндофунктором категории Hask, то есть сохраняет в ней единичный морфизм и композицию морфизмов, но так как один fmap сохраняет, то и два последовательно применённых fmap будут сохранять:
(fmap . fmap) id ≡ fmap (fmap id) ≡ fmap id ≡ id

 (fmap . fmap) (f . g) ≡
≡ fmap (fmap (f . g)) ≡ 
≡ fmap ((fmap f) . (fmap g)) ≡
≡ (fmap (fmap f)) . (fmap (fmap g)) ≡
≡ ((fmap . fmap) f) . ((fmap . fmap) g)
Что и требовалось доказать. Композиция функторов, так же как и тождественный функтор, естественная и простая конструкция, но тем не менее полезная, и понадобится она нам снова, когда мы дойдём до монад.

Итак, чтобы построить категорию с объектом Hask и эндофункторами в качестве морфизмов, осталось проверить две аксиомы:
  • Ассоциативность композиции
        ((φ :.: ψ) :.: ω) α ≡ (φ :.: ψ) (ω α) ≡ 
                             ≡ φ (ψ (ω α)) ≡ 
                             ≡ φ ((ψ :.: ω) α) ≡ (φ :.: (ψ :.: ω)) α
    
    Действие на морфизмах (fmapφ . fmapψ) – это обычная композиция, её ассоциативность мы уже проверяли в прошлый раз.
  • Нейтральность единичного морфизма
        (φ :.: Id) α ≡ φ (Id α) ≡ φ α ≡ Id (φ α) ≡ (Id :.: φ) α 
    
        fmap . id ≡ id ≡ id . fmap
    
Всё в порядке!

Структура моноида


На самом деле, наше знакомство с моноидами уже состоялось, так как описанная выше категория является моноидом. Давайте отфильтруем избыточную информацию о ней и оставим только определение:
Моноид – это категория с одним объектом

Вот так просто. Из этой формулировки сразу становится понятно, почему у него такое название: “моно” значит “один”.

Приведу ещё один пример категорного моноида. Рассмотрим подкатегорию категории Hask, с одним объектом Int. В качестве морфизмов возьмём функции следующего вида λn → n + k или коротко (+k) для каждого k ∷ Int, то есть (+(-1)), (+7), (+100500) и т.д. Вместе с обычной композицией и (+0) ≡ id получается категория. Можно представить себе все значения типа Int на числовой прямой и действие на них этих морфизмов следующим образом:
          Int:   …  -5  -4  -3  -2  -1   0   1  …
(+(-2)) ∷  ↑         ↑   ↑   ↑   ↑   ↑   ↑   ↑ 
          Int:   …  -3  -2  -1   0   1   2   3  …
  (+3)  ∷  ↓         ↓   ↓   ↓   ↓   ↓   ↓   ↓ 
          Int:   …   0   1   2   3   4   5   6  …
То есть визуально это сдвиги начала координат (0) на заданное число позиций, хотя в целом числовая прямая остаётся той же. Что нам даёт структура категории: во-первых, есть единичный морфизм, который оставляет всё на месте, во-вторых, есть композиция морфизмов, она ассоциативна и id нейтрален относительно неё. Если m и n – два целых числа, то композиция устроена так:
(+m) . (+n) ≡ (+(m+n)) 
То есть на самом деле, она действует как сумма. Можно думать о каждом морфизме (+m) как просто о числе m (то, куда мы сдвинули начало координат: (+m) 0 ≡ m), тогда “композиция” m и n – действительно их сумма: (m+n), а единичный морфизм – просто ноль.

Этот ракурс соответствует теоретико-множественному определению моноида:
Моноид – это тройка, состоящая из множества, ассоциативной бинарной операции на этом множестве и элемента, нейтрального относительно этой операции

В данном примере это такая тройка: (Int, (+), 0).
(l + m) + n ≡ l + (m + n)
m + 0 ≡ m ≡ 0 + m

В этом определении просто переформулируются аксиомы категории: множество – это множество морфизмов, ассоциативная бинарная операция – это композиция морфизмов, а нейтральный элемент – это единичный морфизм. Важно понимать, что с какой бы стороны мы ни смотрели на структуру моноида, главное – это ассоциативность бинарной операции и наличие нейтрального элемента.

Посмотрим теперь на класс Monoid в Haskell:
class Monoid μ where
    mappend ∷ μ → μ → μ
    mempty  ∷ μ
где μ – рассматриваемое множество, mappend – операция, которая должна быть ассоциативна, mempty – элемент, который должен быть нейтрален относительно mappend. Для тройки (Int, (+), 0) воплощение этого класса будет непосредственным:
instance Monoid Int where
    mappend = (+)
    mempty  =  0

Аналогично для любой другой тройки, например (Float, (*), 1) или ([α], (++), []) или (Bool, (||), False), где || – логическое “или”. Но мы можем воплотить и категорное определение, ещё раз продемонстрировав их связь:
type Mor α = α → α

instance Monoid (Mor α) where
    mappend = (.)
    mempty  = id
    
В данном случае тип α ∷ ∗ – объект категории Hask, функции типа Mor α – морфизмы на этом объекте. Вместе с обычной композицией и единичным морфизмом id они образуют категорию с одним объектом, то есть моноид.

В модуле Data.Monoid есть похожее воплощение для типа Endo. Кстати говоря, почти все воплощения в этом модуле делаются для типов “в обёртках”. Это делается потому, что на одном и том же множестве моноидальную структуру можно ввести разными способами. Например для типа Int, кроме рассмотренной структуры (Int, (+), 0) (ср. Sum) можно также рассмотреть (Int, (*), 1) (ср. Product), а для типа Bool кроме упомянутой (Bool, (||), False) (см. Any) есть (Bool, (&&), True) (см. All).

Уйму примеров таких троек-моноидов можно найти в хабра-статье “Моноиды и их приложения: моноидальные вычисления в деревьях”. Кроме того, об использовании моноидов в Haskell можно почитать статью-перевод в журнале Практика функционального программирования. Ну а если без картинок совсем грустно, есть перевод главы про моноиды из учебника Learn You a Haskell for Great Good!

Заключение


Читателю может показаться, что я перевернул всё с ног на голову с этими разными определениями моноида, но я просто хотел показать, что важна сама структура, а не то, на чём она построена: на элементах множества, морфизмах категории или на чём-либо ещё.

На самом деле, во всей этой теории речь идёт о разных видах стрелок (отображений, преобразований). Можно отождествить объекты с единичными морфизмами и не говорить больше об объектах в дальнейших построениях (нужна только индексация единичных морфизмов, как обозначение, а область и кообласть морфизмов нужны только для корректной конструкции композиции).

Мы уже знаем о морфизмах, как о стрелках между объектами, знаем о функторах, как о стрелках между категориями. А какова природа стрелок между функторами? Такие стрелки называются естественными преобразованиями (natural transformations) и о них я расскажу в следующий раз.

Подводя итог этой статьи, я хочу ещё раз повторить основные рассмотренные понятия и связать их воедино:
Эндофункторы категории Hask вместе с композицией функторов и тождественным функтором обладают структурой моноида

Эта ключевая фраза окажется нам крайне полезной, когда речь пойдёт о (строго) моноидальной категории, которую мы построим из функторов и естественных преобразований.
+27
1480
26

Комментарии (43)

+5
Darkus, #
Отлично. Благодарю за продолжение. Однако не могу не отметить, что текст стал несколько сложнее для понимания. Отчасти, как мне кажется, это связано с многочисленными новыми обозначениями и определениями. Тем не менее, продолжайте — Вы задумали отличную серию статей. И в моём лице Вы всегда найдёте поддержку.

Кстати, отличная находка — слово «воплощение» как перевод термина instance. Однако в литературе уже устоялся перевод «экземпляр» :).
+3
laughedelic, #
Спасибо. А скажите, текст стал сложнее по содержанию или по изложению? Я так понимаю, что говоря о многочисленных новых обозначениях и определениях, Вы имеете ввиду второе, но достаточно ли просто объясняется то, что кроется за вводимыми обозначениями?

Я смотрю на всё это следующим образом:
С одной стороны введение терминологии и обозначений далеко не всегда является необходимым, но с другой стороны, оно нацеленно на то, чтобы упростить дальнейшее изложение, сделать его язык более высокоуровневым. Другое дело, что для того, что для того, чтобы читатель мог легко понимать этот новый язык, он должен приобрести интуитивное восприятие вводимых терминов, чтобы читая их не расшифровывать каждый раз, а понимать в целом. И задача автора в том, чтобы упростить формирование этой интуиции у читателя — с помощью наглядных примеров, аналогий и экстраполяций.

Вероятно, мои тексты далеко не соответствуют описанной методологии, но я к этому стремлюсь, поэтому я буду рад любой конструктивной, конкретной критике и постараюсь учесть ошибки в дальнейшем.

Насчёт перевода «instance» как «воплощение» — я встречал такой вариант в Мягком введении в Haskell. И мне кажется, это слово достаточно хорошо отражает смысл понятия класс как абстракции, которую воплощают в себе конкретные сущности. «Экземпляр» же с одной стороны отражает суть класса как совокупности типов, что тоже хорошо. Думаю, стоит чередовать эти термины, поскольку они не противоречат друг другу ")
+2
laughedelic, #
По-моему, когда нажимаешь «Ответить» -> «Предпросмотр» -> «Написать», комментарий постится не туда "/
+2
Darkus, #
Я не могу быть беспристрастным судьёй, поскольку я и до того всё описанное прекрасно понимал и осознавал. Только вот даю Вам своё интуитивное понимание — текст стал сложнее. Полагаю, что отсутствие многочисленных комментариев (по сравнению с предыдущей частью, к примеру) подтверждает мою интуицию.

По поводу воплощения. Придумалось такое: экземпляр воплощает класс в типе. Нормально, на мой взгляд :).
+2
laughedelic, #
Ага.
«экземпляр воплощает класс в типе» – это хорошо, ёмко.
+6
erlyvideo, #
它走完 категории 的厂房 и их 来体验 структура.

Но я честно как-нибудь попытаюсь разобраться в том, о чём написано.
+2
Darkus, #
:D
+2
laughedelic, #
(: Хотелось просто сделать название ёмким.
Вы спрашивайте, если что непонятно – буду рад разъяснить (;
+2
mikhanoid, #
α ↦ Maybe α ↦ [Maybe α] — а вто тут что за странный квадратик? И какой Вы используете шрифт? А то я попробовал всяко разные, везде этот квадратик отображается квадратиком.
+3
laughedelic, #
Хм,, даже не думал, что у кого-то возникнут проблемы с юникодовскими символами… У меня в браузере по умолчанию шрифты Times и Courier. Пока писал, в редакторе использовал Monofur.
А какой именно символ у Вас отображается квадратиком? Просто Вы скопировали из поста видимо и оно у меня в тут и там нормально всё выглядит. Там написано: a -> Maybe a -> [Maybe a]. Только вместо «a» – альфа, а вместо "->" – другая стрелочка, что-то типа |-->.
+3
mikhanoid, #
Стрелочка и некоторые другие. Видимо, это какая-то проблема со шрифтами у меня, потому что на другой машине с точно таким же Firefox всё показывается нормально. Буду разбираться.
+2
mikhanoid, #
А я тут, как обычно, с критикой :) А чем, собственно, вот эти все построения отличаются от понятия полугруппы с единицей (ну, того же моноида теоретико-множественного). То есть, мы уже знаем, из предыдущей математики, что существуют такие полугруппы, в том числе и для отображений с композицией. Эмс. В чём смысле перезаписи этого понятия в терминах теории категорий? Или это станет понятно из следующей публикации?
+1
Darkus, #
Моноид — это и есть полугруппа с единицей. В ТК он определяется абсолютно также. Инструментарий и отчасти область применения ТК иные, чем у теории множеств.
+3
mikhanoid, #
Думается, что многим было бы интересно почитать именно про особенности применения ТК (определения и так все знают, они не такие уж и сложные). А раз есть моноид и теоретикомножественный и теоретикокатегорный, то на его примере можно было бы как раз и показать отличия. Вот. Я бы с удовольствием такое бы почитал. Потому что пока в интернете я наталкиваюсь именно на определения ТК и на описание того, чему они соответствуют в других областях математики.
+3
Darkus, #
Да, это было бы интересно. Поскольку ТК — это довольно-таки абстрактная наука, то описание методов её применимости на практике было бы интересно прочитать и обсудить.

За себя могу сказать, что определения ТК позволяют мне писать более качественный код в функциональном стиле. Но это очень интуитивное дело, так просто словами не выразить.
+4
mikhanoid, #
Значит, надо выражать примерами :) Можно ли какие-нибудь привести с указанием: а вот на это решение повлияло знание ТК. Даже без объяснения, как именно повлияло, это был бы весьма интересный материал.
+3
Darkus, #
Я сейчас как раз над статьёй для Хаброхабра думаю. Возможно, в неё включу.
+3
lomeo, #
Как пример, можно почитать про подход Denotational design with type class morphisms.

Если очень кратко, то можно увидеть общее там, где раньше не замечал. Плюс такой подход сам вынуждает писать в такой манере.

В общем, в Haskell-е надо использовать моноиды-функторы-аппликативные функторы-монады-стрелки вовсю. И, говорят, будет счастье.
+3
laughedelic, #
Это действительно одно и то же. Вот что пишет Маклейн:
«Моноид – это категория с одним объектом. Как следствие, моноид определяется множеством своих стрелок, единичной стрелкой и правилом композиции стрелок. Поскольку произведение определено для любой пары стрелок, то моноид можно описать как множество M с бинарной операцией M x M --> M, ассоциативной и имеющей единицу. Таким образом, моноид – то же самое, что полугруппа с единицей

(«Категории для работающего математика», Гл 1.2)

Разница просто в используемой терминологии. С точки зрения изложения материала, я посчитал, что правильнее привести сначала пример того, что читатель уже знает – категории, но именно категории с одним объектом и потом объяснить, что уже известные категорные аксиомы, в данном частном случае, называются структурой моноида. А потом можно объяснять другие ипостаси этого понятия и приводить примеры множеств с бинарной операцией. Я предполагаю, что читатель может ничего не знать о теории групп и потому не лезу в отдельную теорию, которая не является необходимой для основной темы статьи ")
+1
Darkus, #
Мне кажется, что массовый читатель больше знает о теории групп, чем о теории категорий. Просто в силу того, что в технических ВУЗах теорию групп преподают, а теорию категорий, скорее всего, нет.
+2
laughedelic, #
Так-то оно так. Но я рассчитываю всё же на не подготовленного читателя: думаю, на хабре в основном программисты, которые хотя и учились в техническом вузе, давно забыли теорию групп и прочую абстрактную алгебру.
.
В любом случае я не вижу проблем с теми, кто знает теорию групп — я ведь никого не обманываю эквивалентными определениями — напротив, таким подкованным читателям по-моему полезно взглянуть на знакомое понятие с нового ракурса.

+2
Darkus, #
Согласен.
0
mikhanoid, #
А почему теория групп перестала быть частью абстрактной алгебры? Наверное 3/4 книги «Прикладная абстрактная алгебра» посвящена именно теории групп :) И забывать её уж точно не нужно, ибо используется она в огромном количестве алгоритмов.
+2
laughedelic, #
Я не говорил, что она не является частью. «теорию групп и прочую абстрактную алгебру» – значит одна часть и все остальные части целого. А насчёт нужно забывать или нет – к чему говорить о долге, я говорю о том, что многие действительно забывают. Или Вы рассчитываете, что все помнят, постоянно используют и понимают это?
+1
mikhanoid, #
Ну. Собственно, мой вопрос был не о том, почему именно в этой стетье рассказывается о ТК-моноиде. Это понятно. Программисты на Haskell её любят. Вопрос в другом: а какие преимущества даёт TK подход?
+2
laughedelic, #
Ну если говорить в общем, наверное, jtootf ответил на Ваш вопрос…
+2
jtootf, #
Категориальное определение облегчает дальнейшее обобщение понятий. В случае моноида — на произвольные категории и n-категории: топологические группы, группы Ли, 2-моноиды и прочие представители семейства получаются из определения тривиальным образом. Ну и в пределе — можно красивой табличной нарисовать стабилизационную гипотезу Баеца-Долана.
0
mikhanoid, #
А смысл? Например, группы Ли же полезны не как абстрактные группы, а как группы вполне определённых симметрий. Какая польза от определения их именно в терминах ТК? Вот чего я не понимаю…
+3
jtootf, #
Понятие полезности надо как-то строго определять, потому как у разных людей оно разное. В категориальном определении, прежде всего, есть высокий уровень абстракции: мы не обращаем внимания на внутреннее устройство, зато легко можем заметить место структуры в иерархии.

Так, в теории множеств мы определяем декартово произведение, а в теории категорий — произведение в общем, как предел. Следствием этого является то, что поменяв подлежащую категорию (гарантировав лишь, что она обладает соответствующими пределами) мы получаем новую конструкцию, что называется, бесплатно. А рассмотрев её свойства, делаем выводы о проблемах применимости теоретико-множественных подходов к категории Гильбертовых пространств (например).

То же самое о группах. Если вас интересует их структура и свойства как объекта, теоретико-категориальный подход вряд ли будет удачным решением. Но если вас интересует структура взаимодействий, общие и различные аспекты разных частных случаев, нетривиальные обобщения — куда как проще будет воспользоваться специально разработанным для этого языком. Учитывая тематику сайта, ТМ — это структурное программирование, а ТК — ООП: в первом случае нас интересует структура, во втором — интерфейсы.
+3
jtootf, #
Ну и да, в данном конкретном случае теоретико-категориальный подход хорош как минимум потому, что монаду теоретико-множественно вводить уж очень неудобно — в то время, как обобщение от ТК-моноида делается тривиально.
+1
Darkus, #
Монада над категорией — это моноид над эндофункторами данной категории с композицией в качестве умножения и тождественным эндофунктором в качестве единицы. Так?

Но что-то мне подсказывает, что для непосвящённого это звучит как:

它走 над категорией — это 走完 над 它完体 данной категории с 的厂 в качестве 房验 и тождественным 它完体 в качестве 来体.
+2
laughedelic, #
Я вот вашу формулировку не очень понимаю. Особенно «моноид над эндофункторами». Позвольте я распишу чуть подробнее:
Монада – это моноидальный объект в моноидальной категории эндофункторов.

Моноидальная категория эндофункторов:
  • Объекты: эндофункторы некоторой категории С.
  • Морфизмы: естественные преобразования.
  • Моноидальная структура:
    • Умножение: композиция функторов.
    • Единица: тождественный функтор.

Моноид (моноидальный объект) в этой категории – это объект с двумя морфизмами (опять умножение и единица), то есть функтор с двумя ест. преобр-ми. Это и есть монада.

Думаю так иероглифов меньше… не?
+1
Darkus, #
Мне кажется, что я то же самое выразил, только короче (возможно, менее строго).

А в Вашей формулировке иероглифов, всё же, больше.
+2
laughedelic, #
Ну вот меня просто смущает, что частенько говорят, «моноид» вместо более точного «моноидальный объект» – и так и так конечно правильно, но первое можно неправильно истолковать.
+1
Darkus, #
Но ведь «моноидальный объект» — это же объект категории, представляющий собой моноид?
+2
laughedelic, #
Да. Но когда говорят просто «моноид в категории», имхо, не очень понятно, что это такой особый объект-моноид.
+2
jtootf, #
А можно так: моноид — это дегенеративная (одноэлементная) категория. 2-моноид, соответственно, дегенеративная 2-категория.
+3
ulysses, #
Эх, надеялся, что вы уже в этом посте доберётесь до монад… Отличные статьи! Продолжайте, пожалуйста!
+2
laughedelic, #
Спасибо ") Монады постараюсь охватить в следующей части. Хотя вообще-то, я хотел написать следующую часть про естественные преобразования, а уже в 4й собрать всё воедино и преподнести монады, как венец всех этих… абстракций ")
Боюсь, что если всё запихнуть в одну часть, получится скомкано и сложно… После того, как я понял, что вторая часть пошла хуже из-за каких-то сложностей в изложении, я с трудом оцениваю степень подробности, с которой надо писать дальше…
+3
ulysses, #
Вы лучше не торопитесь и делайте так, как собирались. Также помните, что примеры — ваши главные друзья. Советовать что-то более конкретное не стану, потому что, во-первых, думаю, что это не в последнюю очередь вопрос творческий, и вам нужно доверять своей интуиции и вдохновению, а во-вторых, потому что у меня есть кое-какой теоркатегорный бэкграунд, и говорить что делать, чтобы статьи стали более доступны хабровчанам, я не считаю возможным.
+2
laughedelic, #
Спасибо. Да, постараюсь подготовить хорошие примеры и иллюстрации.
+1
m03r, #
Отличные статьи (обе)! Написаные для программистов, а не для математиков, они радуют меня с недавних пор привычными хаскельными обозначениями. Теперь жду про монады :-)

Спасибо!
0
laughedelic, #
Спасибо ") Рад, что Вам понравилось!
К сожалению, продолжение откладывается, в связи с тем, что я сейчас очень занят дипломом. Но когда появится свободное время, обязательно напишу про естественные преобразования, монады и, возможно, ещё некоторые темы связанные с математикой, осознанной через призму хаскеля. В ходе работы над дипломом много таких интересных вещей накапливается, но, к сожалению прямо сейчас нет времени на то, чтобы писать о них статьи… "(

Только зарегистрированные пользователи могут оставлять комментарии.
Войдите, пожалуйста.