Монада - это просто моноид из категории эндофункторов, в чем проблема?

Кто первым сказал следующее?

Монада - это просто моноид из категории эндофункторов, в чем проблема?

И менее важное замечание: верно ли это, и если да, то не могли бы вы дать объяснение (надеюсь, такое, которое сможет понять тот, кто не имеет большого опыта работы с Haskell)?


person Roman A. Taycher    schedule 06.10.2010    source источник
comment
См. Категории для работающего математика   -  person Don Stewart    schedule 06.10.2010
comment
Вам не нужно понимать это, чтобы использовать монады в Haskell. С практической точки зрения это просто умный способ обойти штат через подземную водопроводную сеть.   -  person starblue    schedule 07.10.2010
comment
Я также хотел бы добавить сюда этот отличный пост в блоге: stephendiehl.com/posts/monads.html Это не дает прямого ответа на вопрос, но, на мой взгляд, Стивен отлично справляется со связью категорий и монад в Haskell. Если вы прочитали ответы выше - это должно помочь объединить два взгляда на это.   -  person Ben Ford    schedule 01.08.2013
comment
Точнее, для любой категории C категория [C, C] ее эндофункторов имеет моноидальную структуру, индуцированную композицией. Моноидный объект в [C, C] - это монада в C. - из en.wikipedia.org/wiki/Monoid_%28category_theory%29. См. En.wikipedia.org/wiki/Monad_%28category_theory%29 для определения монады в теории категорий.   -  person    schedule 23.06.2015
comment
ммм, я потратил больше года на размышления о Haskell, и я до сих пор не могу с уверенностью понять, что такое функтор (это объект функции? объект, который вы можете сопоставить? функция, принимающая и возвращающая M a? двоичная функция, принимающая и возвращая M a? Как вы можете отобразить функцию, если у нее нет элементов для перебора ...) Не говоря уже о том, что такое эндофунктор. Я понимаю, что fmap позволяет применить функцию к объекту в рамке, а ›› = позволяет вставить объект M в рамке в функцию a - ›M a, но что теперь?   -  person Dmitry    schedule 22.09.2016
comment
@Dmitry функтор - это функция между категориями с некоторыми ограничениями, которые необходимо соблюдать. Эндофунктор в категории C - это просто функтор из C в себя. Data.Functor - это класс типов для эндофункторов на Категория хасков. Поскольку категория состоит из объектов и морфизмов, функтор должен отображать и то, и другое. Для экземпляра f объекта Data.Functor карта объектов (типов haskell) - это сама f, а карта морфизмов (функции haskell) - это fmap.   -  person Matthijs    schedule 29.10.2016
comment
См. Здесь точное, но человеческое объяснение: stackoverflow.com/questions/2704652/   -  person Dmitri Zaitsev    schedule 29.11.2016
comment
См. Блестящую серию лекций Бартоша Милевски для получения полной информации по категории «Теория для программистов». На протяжении всего этого Бартош устанавливает необходимые предварительные условия в теории категорий, всегда связываясь с Haskell. Последняя часть на самом деле называется моноид в категории endofunctors и полностью отвечает на вопрос.   -  person michid    schedule 09.01.2018
comment
Такое чувство, что математики, которые изобрели этот термин, изначально никогда не задумывались о концепциях, лежащих в основе этих терминов. Они подумали о конкретной проблеме и дали ей название. Подобные определения редко отражают стоящие за ними идеи. Я считаю, что хорошему определению всегда предшествует контекст и связанные термины.   -  person Pavel Sapehin    schedule 25.04.2020


Ответы (5)


Эта фраза принадлежит Джеймсу Айри из его очень занимательного Краткая, неполная и в основном неверная история языков программирования, в которой он вымышленно приписывает ее Филиппу Уодлеру.

Оригинальная цитата взята из Сондерса Мак Лейна в Категории для работающего математика, одном из основополагающих текстов теории категорий. join в Haskell)

  • Естественное преобразование, η: I → T, где I - это эндофунктор идентичности на X ( η известен как return < / a> в Haskell)
  • ... удовлетворяющие этим законам:

    • μ ∘ Tμ = μ ∘ μT
    • μ ∘ Tη = μ ∘ ηT = 1 (тождественное естественное преобразование)

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

    person Tom Crockett    schedule 06.10.2010
    comment
    Спасибо за объяснение и спасибо за статью «Краткая, неполная и в основном неверная история языков программирования». Я думал, что это может быть оттуда. Поистине один из величайших юморов программирования. - person Roman A. Taycher; 06.10.2010
    comment
    Это фантастическое объяснение, но у меня есть один вопрос. Я понимаю, что моноидальный продукт имеет тип S × S -> S, но каков еще один пример того, что такое ×, вне контекста композиции функторов? Например, может быть умножением или сложением натуральных чисел; что такое × в этом контексте? - person Jonathan Sterling; 20.10.2010
    comment
    @Jonathan: В классической формулировке моноида × означает декартово произведение множеств. Подробнее об этом можно прочитать здесь: en.wikipedia.org/wiki/Cartesian_product, но основная идея состоит в том, что элементом S × T является пара (s, t), где s ∈ S и t ∈ Т. Таким образом, сигнатура моноидального произведения •: S × S - ›S в этом контексте просто означает функцию, которая принимает 2 элемента S в качестве входных данных и производит другой элемент < i> S в качестве вывода. - person Tom Crockett; 20.10.2010
    comment
    Я думаю, что Monoid Maclane, о котором идет речь, является немного более общим, чем тот, который вы описали, потому что набор представляет собой некоторый объект в некоторой категории, а операции являются морфизмом, не обязательно определяемым в терминах элементов. И в данном конкретном случае это категория эндофункторов, в которой произведение двух объектов (где объекты являются функторами) вместо декартового произведения представляет собой композицию функторов ... что выглядит довольно иначе, хотя у меня нет хорошее интуитивное понимание того, что это значит. - person Owen; 03.01.2012
    comment
    Меня смущает ваше определение моноида, а именно: элемент S, e: 1 - ›S. Итак, e является элементом S, но тогда вы определяете его как e: 1 - ›S, что означает, что e - это функция с доменом 1 и codomain S. Что это значит? - person Tahir Hassan; 01.11.2012
    comment
    @TahirHassan - В общих чертах теории категорий мы имеем дело с непрозрачными объектами вместо множеств, поэтому априорное понятие элементов отсутствует. Но если вы подумаете о категории Set, где объекты являются наборами, а стрелки - функциями, элементы любого набора S находятся во взаимно однозначном соответствии с функциями из любого одноэлементного набора, равного S. То есть для любого элемента e из S существует ровно одна функция f: 1 - ›S, где 1 - это любой одноэлементный набор ... (продолжение) - person Tom Crockett; 02.11.2012
    comment
    Одноэлементные наборы @TahirHassan сами по себе являются специализациями более общего теоретико-категориального понятия терминальных объектов: терминальный объект - это любой объект категории, для которого есть ровно одна стрелка от любого другого объекта к нему (вы можете проверить, что это верно для наборов из 1 элемента в Set). В теории категорий терминальные объекты просто обозначаются как 1; они уникальны с точностью до изоморфизма, поэтому различать их нет смысла. Итак, теперь у нас есть чисто теоретико-категориальное описание элементов S для любого S: это просто стрелки от 1 к S! - person Tom Crockett; 02.11.2012
    comment
    @TahirHassan - Чтобы выразить это в терминах Haskell, подумайте о том факте, что если S является типом, все, что вы можете сделать при написании функции f :: () -> S, - это выбрать какой-то конкретный термин типа S (его элемент, если хотите) и верните его ... вы не получили никакой реальной информации с аргументом, поэтому нет возможности изменить поведение функции. Итак, f должна быть постоянной функцией, которая каждый раз возвращает одно и то же. () (Unit) - конечный объект категории Hask, и неслучайно существует ровно 1 (недивергентное) значение, которое его населяет. - person Tom Crockett; 02.11.2012
    comment
    @TahirHassan Итак, хотя стрелки от конечного объекта к объекту S - это не то же самое, что и элементы S, они изоморфны его элементам, что с точки зрения теории категорий не хуже. - person Tom Crockett; 02.11.2012
    comment
    Итак, µ - это соединение, а η - возврат, верно? (По крайней мере, в мире Haskell) - person Yet Another Geek; 25.04.2014
    comment
    Хороший способ сказать это одним предложением: Монады - это просто каналы (связанных) преобразований «контейнера» (содержимого). Читайте «каналы (связанные)» как «моноидальный», «контейнер» как «Категория» и «… преобразования» как «функторы», и у вас есть предложение, эквивалентное процитированному. По сути, монады - это сборочные линии (дис). ^^ - person Evi1M4chine; 28.07.2014
    comment
    Я смущен, поскольку моя (неправильная) интуиция говорит, что монады более абстрактны, чем моноиды (поскольку они имеют дело с эндофункторами и преобразованиями, которые кажутся более абстрактными, чем множества и элементы). Но из объяснения выше (которое, очевидно, верно), монады - это конкретизация моноидов? Очевидно, я этого не понимаю. - person Ivan Gozali; 16.11.2014
    comment
    @IvanGozali Теория множеств - это одна из настроек, в которой вы можете определить, что такое моноид; теория категорий - другая, более абстрактная установка. Теоретико-множественное определение моноида является лишь одним частным случаем теоретико-категориального определения (когда рассматриваемая категория - Набор), а монады - это другой частный случай. (когда категория является категорией эндофункторов над другой категорией). Дополнительные примеры моноидов см. В приведенных здесь примерах. Итак, моноиды - более абстрактное понятие. - person Tom Crockett; 10.04.2015
    comment
    Категория эндофункторов называется моноидальной категорией. Делает ли это категория эндофункторов сама также моноидом? Если да, всегда ли моноидальные категории содержат моноиды как объекты? Всегда ли моноиды входят в какую-то моноидальную категорию? - person CMCDragonkai; 13.04.2015
    comment
    Все ли объекты в моноидальной категории являются моноидом? Или некоторые объекты могут быть не моноидом? - person CMCDragonkai; 13.04.2015
    comment
    @CMCDragonkai К вашему первому вопросу, цитируя страницу wikipedia, существует общее понятие моноидного объекта в моноидальной категории, которая обобщает обычное понятие моноида. В частности, строгая моноидальная категория может рассматриваться как моноидный объект в категории категорий Cat (с моноидальной структурой, индуцированной декартовым произведением). - person Tom Crockett; 13.04.2015
    comment
    @CMCDragonkai Строгая моноидальная категория - это категория, для которой естественные изоморфизмы α, λ и ρ тождественны. Каждая моноидальная категория моноидально эквивалентна строгой моноидальной категории. - person Tom Crockett; 13.04.2015
    comment
    @CMCDragonkai, чтобы ответить на ваш второй вопрос, нет, не все объекты в моноидальной категории обязательно являются моноидами. Например, Set - это моноидальная категория, как мы наблюдали выше, но возьмите пустой набор ∅ ... он не может быть моноидальным, потому что не может быть единичного морфизма η: 1 → ∅. Напомним, что в случае Set морфизмы - это функции, а единичный объект (I) - это любой одноэлементный набор. - person Tom Crockett; 13.04.2015
    comment
    @TomCrockett, спасибо! Чтобы упростить, моноидальные категории являются категориальным представлением классического определения моноида? - person CMCDragonkai; 14.04.2015
    comment
    @CMCDragonkai Ну, теоретико-категориальная версия - это обобщение идеи, которое позволяет нам классифицировать как моноиды больше вещей, чем это делает теоретико-множественное определение. Это связано с тем, что законы ассоциативности и тождества задаются в терминах естественных изоморфизмов вместо простых равенств (они являются равенствами с точностью до естественного изоморфизма) - person Tom Crockett; 14.04.2015
    comment
    @CMCDragonkai Один из способов уловить более простую теоретико-множественную идею моноида в теории категорий - сказать, что это любой моноидный объект в моноидальной категории Set, как обсуждалось выше ... - person Tom Crockett; 14.04.2015
    comment
    @CMCDragonkai другой, более простой способ заключается в следующем: моноид в теоретико-множественном смысле - это (небольшая) категория только с одним объектом. Просто подумайте о композиции морфизмов как о моноидной операции, о тождественном морфизме отдельного объекта как о моноидной единице и о любом другом (эндо-) морфизме как о другом элементе моноида. - person Tom Crockett; 14.04.2015
    comment
    Меня также смущает эквивалентность функции eta η : I → T и return в Haskell. Должна ли функция return быть eta? Я не совсем понимаю отношения. Является ли эта цель определением T как заостренного объекта? - person CMCDragonkai; 14.04.2015
    comment
    @CMCDragonkai Да, return это η. Помните, что η - это естественное преобразование между эндофункторами, поэтому оно параметризуется объектом (в случае Hask - типом); его подпись в Haskell будет выглядеть примерно как η :: I a → T a. I - это эндофунктор идентичности, поэтому мы можем просто написать η :: a → T a, где T - ваш монадический эндофунктор; надеюсь, это напомнит вам о подписи return. - person Tom Crockett; 14.04.2015
    comment
    Давайте продолжим это обсуждение в чате. - person Tom Crockett; 14.04.2015
    comment
    Я знаю, что это старый ответ, но меня беспокоит, что этот популярный ответ дает неправильный контекст и неправильное определение моноида. В книге Мак Лейна моноид может существовать в любой категории. И в указанной категории эндофункторов не требуется прищуривания, чтобы соответствовать его определению моноида. Его моноид в категории множеств был бы вашим (обычным) моноидом. Пожалуйста, проверьте источник. - person Tunococ; 20.07.2016
    comment
    И среди этих эндофункторов некоторые из них могут быть монадами. Монада не является эндофунктором, который просто выполняется для удовлетворения дополнительных свойств. Монада - это эндофунктор, снабженный двумя естественными преобразованиями. Это в том же смысле, что группа не является моноидом, который бывает имеет инверсии для каждого элемента, это моноид, снабженный дополнительной унарной операцией, которая удовлетворяет обратному закону . - person JustAskin; 05.09.2016
    comment
    @barron, если вы действительно хотите быть педантичным, вы можете пойти дальше и сказать, что моноид, снабженный унарной операцией, которая просто происходит для удовлетворения обратного закона, также не является группой. Он также должен быть снабжен доказательством того, что указанная операция удовлетворяет обратному закону! Все зависит от точки зрения, какие реквизиты являются частью объектного языка или метаязыка. - person Tom Crockett; 06.09.2016
    comment
    @TomCrockett Да, например ассоциатор / объединитель в моноидальной категории, но я не пытаюсь быть настолько педантичным. Я хочу сказать, что один и тот же эндофунктор можно (в некоторых случаях) превратить в монаду по-разному, ср. экзотические сферы. Чтобы иметь эндофунктор и спрашивать "Это монада?" это как иметь многообразие и спрашивать, является ли это многообразие дифференцируемым? где на указанном многообразии может существовать несколько различных недиффеоморфных дифференциальных структур. Выражение «Какие из них являются монадами?» Для меня предполагает, что нас волнует только наличие дополнительных данных, а не их содержание. - person JustAskin; 06.09.2016
    comment
    Привет, @TomCrockett. В комментарии вы упомянули, что для любого элемента e из S существует ровно одна функция f: 1 - ›S, где 1 - любой одноэлементный набор. Почему? Я могу понять, что для любого элемента e из S существует ровно одна функция (постоянная функция), отображающая от S до {e}, но похоже, что f, о котором вы упомянули, - это наоборот. ИМО, может быть более одного сопоставления функций от {e} до S. Не могли бы вы сказать мне, где я ошибаюсь? Спасибо! - person Lifu Huang; 24.09.2016
    comment
    @LifuHuang, ты прав, это неправильно сформулировано. Я имел в виду только предыдущее предложение: элементы любого набора S находятся во взаимно однозначном соответствии с функциями из любого одноэлементного набора, равного S, т. Е. существует взаимное соответствие между S и 1 → S. Очевидная биекция переводит любой заданный s ∈ S в {(e, s)}. - person Tom Crockett; 25.09.2016
    comment
    Спасибо, @TomCrockett. И еще один вопрос, потому что у меня нет опыта в теории категорий. Меня немного смущает μ (η (T)) = T = μ (T (η)). Насколько я понимаю, η - это морфизм (или стрелка), указывающий от объекта I к объекту T (ну, конечно, в категории эндофункторов морфизм - это естественное преобразование, как вы упомянули). Тогда что означает η (T)? что меня еще больше озадачивает, так это значение T (η), рассматриваемое как T - объект, а η - это морфизм. Большое спасибо! - person Lifu Huang; 26.09.2016
    comment
    @LifuHuang Здесь вы можете прочитать, что означают обозначения ηT и : en.wikipedia.org/wiki/ ... ваш вопрос заставил меня понять, что мое описание законов монад было непоследовательным, поэтому я переписал его. К сожалению, синтаксическое сходство с моноидными законами уже не так очевидно; Я должен придумать способ сделать это более ясным. - person Tom Crockett; 27.09.2016
    comment
    Еще раз спасибо, @TomCrockett. Я предполагаю, что причина, по которой синтаксическое сходство теперь исчезает, заключается в том, что вы описываете ассоциативность и единицу моноида в Set в терминах элемента a, b, c, в то время как в End нет понятия элемента . Но определение моноида в терминах элементов a, b, c является наиболее (и, вероятно, единственным) приемлемым способом для новичков (таких как я). С моей точки зрения, было бы замечательно, если бы вы, дав определение моноида в Set с точки зрения элементов a, b, c, также разместили общее определение моноида в категории моноидов, а затем объяснили (продолжение) - person Lifu Huang; 27.09.2016
    comment
    как общее определение моноида соответствует определению моноида в Set, а также определению в End. Поскольку я считаю, что большинство людей, не имеющих опыта в теории категорий, не могут связать это определение здесь (en. wikipedia.org/wiki/Monoid_(category_theory)) к их знакомому определению моноида в Set в терминах элементов, не говоря уже об определении моноида в End . - person Lifu Huang; 27.09.2016
    comment
    @LifuHuang ага, вы указали точную сложность! Я подозреваю, что нет никаких ярлыков, и удовлетворительное объяснение требует введения категориального понятия моноида и демонстрации того, как оно специализируется на Set и End соответственно. - person Tom Crockett; 27.09.2016
    comment
    Что ж, это действительно непросто. В любом случае спасибо, это лучший ответ о монаде, который я когда-либо читал :) - person Lifu Huang; 28.09.2016
    comment
    Ой, еще один вопрос. Благодаря вашему подробному объяснению, я понял определение монады в вашем сообщении. Но когда я вернулся, чтобы заново изучить определение монады в языках программирования. Я обнаружил, что свод законов монады (wiki.haskell.org/Monad_laws) выглядит иначе (но похожим ) из того, что есть в вашем посте. Не могли бы вы объяснить, как эти два свода законов соотносятся друг с другом? Какова математическая интерпретация bind? Спасибо еще раз. - person Lifu Huang; 28.09.2016
    comment
    @LifuHuang Лучший способ увидеть, как это определение относится к Haskell, - это отметить, что μ - это join в Haskell и m >>= f = join (fmap f m). Законы монад Хаскелла - это повторение этих законов, но в терминах >>=. Дополнительную информацию см. На этой странице: wiki.haskell.org/Category_theory/Monads. - person Tom Crockett; 28.09.2016
    comment
    Спасибо. Итак, $ \ mu \ circ F (\ mu) = \ mu \ circ \ mu $ на этой странице - это то же самое, что и $ \ mu \ circ T \ mu = \ mu \ circ \ muT $ в вашем ответе, верно? $ F (\ mu) $ для меня выглядит очень странно, это еще одна стандартная нотация? - person Lifu Huang; 28.09.2016
    comment
    @LifuHuang Да, это правильно. Интуиция, стоящая за обозначением F(f), заключается в том, что функтор F: C → D представляет собой карту между категориями и, как таковой, отображает оба объекта в < b> C (F (A)), а также морфизмы в C (F (f)). - person Tom Crockett; 28.09.2016
    comment
    @LifuHuang В Haskell, где под Functor мы подразумеваем эндофунктор на Hask, Functor сопоставляет объекты Hask с другими объектами в Hask. Поскольку объекты Hask являются типами, это просто означает, что Functor экземпляр t может быть применен к типу a для получения другого типа _6 _... т.е. это конструктор типа! И способ Functor экземпляра t отображает функцию f: a -> b на функцию t a -> t b, конечно, через fmap. - person Tom Crockett; 28.09.2016
    comment
    @LifuHuang После написания этих двух комментариев я понял, что на самом деле не ответил на ваш вопрос, потому что здесь сложно то, что мы применяем F не только к морфизму, но и к естественному преобразованию. Интуиция в отношении Haskell заключается в том, что естественные преобразования - это полиморфные функции. Например, id :: forall a. a -> a - это не просто морфизм в Hask, а фактически целое семейство морфизмов - естественное преобразование! Но fmap id :: forall a. Functor f => f a -> f a type проверяет очень хорошо, и именно это обозначение F (μ) означает, когда μ является естественным преобразованием. - person Tom Crockett; 28.09.2016
    comment
    Понятно. Спасибо! Я действительно должен тебе сотню голосов :) - person Lifu Huang; 29.09.2016
    comment
    Думаю, я собираюсь прочитать книгу по теории категорий и перечитать этот комментарий и ответы. У меня такое чувство, что через банкомат у меня в голове крутится какая-то очень полезная штука. - person mbrig; 09.02.2018
    comment
    Прекрасное объяснение. Я просто запуталась в последней части. Разве это не должно быть: μ ∘ Tη = μ ∘ ηT = μ (the identity natural transformation) Почему написано 1? - person corlaez; 03.08.2020

    Во-первых, расширения и библиотеки, которые мы собираемся использовать:

    {-# LANGUAGE RankNTypes, TypeOperators #-}
    
    import Control.Monad (join)
    

    Из них RankNTypes - единственный, который абсолютно необходим для нижеприведенного. Однажды я написал объяснение RankNTypes, которое некоторые люди, кажется, сочли полезным < / a>, поэтому я обращусь к этому.

    Цитируя отличный ответ Тома Крокетта, мы имеем:

    Монада - это ...

    • Эндофунктор, T: X - ›X
    • Естественное преобразование, μ: T × T - ›T, где × означает композицию функторов.
    • Естественное преобразование, η: I - ›T, где I - это эндофунктор идентичности на X

    ... удовлетворяющие этим законам:

    • μ(μ(T × T) × T)) = μ(T × μ(T × T))
    • μ(η(T)) = T = μ(T(η))

    Как нам перевести это в код Haskell? Что ж, давайте начнем с понятия естественного преобразования:

    -- | A natural transformations between two 'Functor' instances.  Law:
    --
    -- > fmap f . eta g == eta g . fmap f
    --
    -- Neat fact: the type system actually guarantees this law.
    --
    newtype f :-> g =
        Natural { eta :: forall x. f x -> g x }
    

    Тип формы f :-> g аналогичен типу функции, но вместо того, чтобы думать о нем как о функции между двумя типами (типа *), думайте о нем как о морфизм между двумя функторами (каждый вида * -> *). Примеры:

    listToMaybe :: [] :-> Maybe
    listToMaybe = Natural go
        where go [] = Nothing
              go (x:_) = Just x
    
    maybeToList :: Maybe :-> []
    maybeToList = Natural go
        where go Nothing = []
              go (Just x) = [x]
    
    reverse' :: [] :-> []
    reverse' = Natural reverse
    

    По сути, в Haskell естественные преобразования - это функции из одного типа f x в другой тип g x, так что переменная типа x недоступна для вызывающего. Так, например, sort :: Ord a => [a] -> [a] нельзя превратить в естественное преобразование, потому что он разборчив в том, какие типы мы можем создать для a. Я часто думаю об этом интуитивно следующим образом:

    • Функтор - это способ работы с содержимым чего-либо, не затрагивая структуру.
    • Естественное преобразование - это способ работы с структурой чего-либо без касания и просмотра содержимого.

    Теперь, разобравшись с этим, давайте займемся пунктами определения.

    Первое предложение - это эндофунктор, T: X - ›X. Что ж, каждый Functor в Haskell является эндофунктором в том, что люди называют категорией Hask, чьи объекты являются типами Haskell (типа *) и чьи морфизмы являются функциями Haskell. Это звучит как сложное утверждение, но на самом деле это очень тривиально. Все это означает, что Functor f :: * -> * дает вам средства создания типа f a :: * для любого a :: * и функции fmap f :: f a -> f b из любого f :: a -> b, и что они подчиняются законам функторов.

    Второе предложение: функтор Identity в Haskell (который поставляется с платформой, поэтому вы можете просто импортировать его) определяется следующим образом:

    newtype Identity a = Identity { runIdentity :: a }
    
    instance Functor Identity where
        fmap f (Identity a) = Identity (f a)
    

    Таким образом, естественное преобразование η: I - ›T из определения Тома Крокетта может быть записано таким образом для любого Monad экземпляра t:

    return' :: Monad t => Identity :-> t
    return' = Natural (return . runIdentity)
    

    Третье предложение: композиция двух функторов в Haskell может быть определена следующим образом (что также входит в состав платформы):

    newtype Compose f g a = Compose { getCompose :: f (g a) }
    
    -- | The composition of two 'Functor's is also a 'Functor'.
    instance (Functor f, Functor g) => Functor (Compose f g) where
        fmap f (Compose fga) = Compose (fmap (fmap f) fga)
    

    Итак, естественное преобразование μ: T × T - ›T из определения Тома Крокетта можно записать так:

    join' :: Monad t => Compose t t :-> t
    join' = Natural (join . getCompose)
    

    Утверждение, что это моноид в категории эндофункторов, означает, что Compose (частично примененный только к его первым двум параметрам) является ассоциативным, и что Identity является его элементом идентичности. То есть выполняются следующие изоморфизмы:

    • Compose f (Compose g h) ~= Compose (Compose f g) h
    • Compose f Identity ~= f
    • Compose Identity g ~= g

    Это очень легко доказать, потому что Compose и Identity оба определены как newtype, а отчеты Haskell определяют семантику newtype как изоморфизм между определяемым типом и типом аргумента конструктора данных newtype. Так, например, давайте докажем Compose f Identity ~= f:

    Compose f Identity a
        ~= f (Identity a)                 -- newtype Compose f g a = Compose (f (g a))
        ~= f a                            -- newtype Identity a = Identity a
    Q.E.D.
    
    person Luis Casillas    schedule 02.05.2014
    comment
    В Natural newtype я не могу понять, что делает ограничение (Functor f, Functor g). Могли бы вы объяснить? - person dfeuer; 20.03.2015
    comment
    @dfeuer На самом деле ничего важного не делает. - person Luis Casillas; 20.03.2015
    comment
    @LuisCasillas Я удалил эти Functor ограничения, поскольку они не кажутся необходимыми. Если вы не согласны, не стесняйтесь добавлять их обратно. - person Lambda Fairy; 21.03.2015
    comment
    Не могли бы вы уточнить, что формально означает, что произведение функторов следует рассматривать как композицию? В частности, каковы проекционные морфизмы для композиции функторов? Я предполагаю, что продукт определен только для функтора F против самого себя, F x F, и только тогда, когда определено join. И это join морфизм проекции. Но я не уверен. - person tksfz; 02.04.2015

    Ответы здесь отлично справляются с определением как моноидов, так и монад, однако, похоже, они все еще не дают ответа на вопрос:

    И менее важное замечание: верно ли это, и если да, то не могли бы вы дать объяснение (надеюсь, такое, которое сможет понять тот, кто не имеет большого опыта работы с Haskell)?

    Суть вопроса, которого здесь не хватает, - это другое понятие «моноид», так называемая категоризация, точнее, понятие моноида в моноидальной категории. К сожалению, сама книга Мак Лейна

    В общем, монада в X - это просто моноид в категории эндофункторов X, где продукт × заменен композицией эндофункторов, а единица задана идентичным эндофунктором.

    Основная путаница

    Почему это сбивает с толку? Потому что он не определяет, что такое «моноид в категории эндофункторов» X. Вместо этого в этом предложении предлагается взять моноид внутри набора всех эндофункторов вместе с композицией функтора как бинарной операцией и функтором идентичности как моноидальной единицей. Что отлично работает и превращает в моноид любое подмножество эндофункторов, которое содержит тождественный функтор и закрыто при композиции функторов.

    Тем не менее, это неправильная интерпретация, которую в книге не проясняет на данном этапе. Монада f - это фиксированный эндофунктор, а не подмножество эндофункторов, закрытых при композиции. Обычная конструкция - использовать f для генерации моноида, взяв с собой набор всех k-кратных композиций f^k = f(f(...)) из f, включая k=0, который соответствует идентичности f^0 = id. И теперь набор S всех этих степеней для всех k>=0 действительно является моноидом, «где произведение × заменено композицией эндофункторов, а единица задана идентичным эндофунктором».

    И все еще:

    • Этот моноид S может быть определен для любого функтора f или даже буквально для любой собственной карты X. Это моноид, созданный f.
    • Моноидальная структура S, заданная композицией функтора и функтором идентичности, не имеет ничего общего с f быть или не быть монадой.

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

    (Строгие) моноидальные категории

    Переходя к главе VII о моноидах (которая идет позже, чем глава VI о монадах), мы находим определение так называемой строгой моноидальной категории как тройной (B, *, e), где B - категория, *: B x B-> B a бифунктор (функтор по отношению к каждому компоненту с фиксированным другим компонентом) и e - это единичный объект в B, удовлетворяющий ассоциативности и законам единиц:

    (a * b) * c = a * (b * c)
    a * e = e * a = a
    

    для любых объектов a,b,c из B, и те же тождества для любых морфизмов a,b,c с e замененным на id_e, морфизм идентичности e. Теперь поучительно заметить, что в нашем интересующем нас случае, где B - категория эндофункторов X с естественными преобразованиями в виде морфизмов, * композиция функторов и e тождественный функтор, все эти законы выполняются, что можно непосредственно проверить.

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

    Моноиды в моноидальных категориях

    Наконец, в разделе 3 «Моноиды» главы VII дано собственное определение:

    Моноид c в моноидальной категории (B, *, e) - это объект B с двумя стрелками (морфизмами)

    mu: c * c -> c
    nu: e -> c
    

    делая 3 диаграммы коммутативными. Напомним, что в нашем случае это морфизмы в категории эндофункторов, которые являются естественными преобразованиями, соответствующими точно join и return для монады. Связь становится еще яснее, когда мы делаем композицию * более явной, заменяя c * c на c^2, где c - наша монада.

    Наконец, обратите внимание, что 3 коммутативные диаграммы (в определении моноида в моноидальной категории) написаны для общих (нестрогих) моноидальных категорий, тогда как в нашем случае все естественные преобразования, возникающие как часть моноидальной категории, на самом деле являются тождествами. Это сделает диаграммы точно такими же, как в определении монады, и соответствие будет полным.

    Заключение

    Таким образом, любая монада по определению является эндофунктором, следовательно, объектом в категории эндофункторов, где монадические операторы join и return удовлетворяют определению моноида в этой конкретной (строгой) моноидальной категории. И наоборот, любой моноид в моноидальной категории эндофункторов по определению является тройкой (c, mu, nu), состоящей из объекта и двух стрелок, например естественные преобразования в нашем случае, удовлетворяющие тем же законам, что и монада.

    Наконец, обратите внимание на ключевое различие между (классическими) моноидами и более общими моноидами в моноидальных категориях. Две стрелки mu и nu выше больше не являются двоичной операцией и единицей в наборе. Вместо этого у вас есть один фиксированный эндофунктор c. Сама по себе композиция функторов 52 и тождественный функтор не обеспечивают полной структуры, необходимой для монады, несмотря на это сбивающее с толку замечание в книге.

    Другой подход заключался бы в сравнении со стандартным моноидом C всех собственных карт набора A, где двоичная операция представляет собой композицию, которая, как можно видеть, отображает стандартное декартово произведение C x C в C. Переходя к категорированному моноиду, мы заменяем декартово произведение x композицией функторов *, а бинарная операция заменяется естественным преобразованием mu из c * c в c, то есть набором операторов join

    join: c(c(T))->c(T)
    

    для каждого объекта T (наберите в программировании). А элементы идентичности в классических моноидах, которые можно идентифицировать с изображениями карт из фиксированного одноточечного набора, заменяются набором операторов return

    return: T->c(T) 
    

    Но теперь декартовых произведений больше нет, поэтому нет пар элементов и, следовательно, нет бинарных операций.

    person Dmitri Zaitsev    schedule 17.08.2019
    comment
    Итак, каков ваш ответ на истинную часть вопроса? Верно ли, что монада является моноидом в категории эндофункторов? И если да, то какова связь между понятием моноида в теории категорий и алгебраическим моноидом (множеством с ассоциативным умножением и единицей)? - person Alexander Belopolsky; 28.03.2020
    comment
    @AlexanderBelopolsky, технически монада - это моноид в моноидальной категории эндофункторов, снабженный функциональной композицией в качестве своего продукта. Напротив, классические алгебраические моноиды являются моноидами в моноидальной категории множеств, снабженных декартовым произведением в качестве своего продукта. Итак, оба являются частными случаями одного и того же категориального определения моноида. - person K. A. Buhr; 23.12.2020

    Я пришел к этому сообщению, чтобы лучше понять вывод печально известной цитаты из статьи Мак Лейна Теория категорий для рабочего математика.

    При описании того, что что-то есть, часто одинаково полезно описать то, чем это не является.

    Тот факт, что Мак Лейн использует это описание для описания монады, может означать, что оно описывает нечто уникальное для монад. Потерпите меня. Чтобы развить более широкое понимание этого утверждения, я считаю, что необходимо прояснить, что он не описывает что-то уникальное для монад; это утверждение в равной степени описывает, среди прочего, Applicative и Arrows. По той же причине у нас может быть два моноида на Int (Sum и Product), у нас может быть несколько моноидов на X в категории эндофункторов. Но это еще не все сходство.

    И Monad, и Applicative соответствуют критериям:

    • endo => любая стрелка или морфизм, который начинается и заканчивается в одном и том же месте
    • functor => any arrow, or morphism between two Categories

      (e.g., in day to day Tree a -> List b, but in Category Tree -> List)

    • моноид => одиночный объект; т.е. одного типа, но в данном контексте только в отношении внешнего слоя; Итак, у нас не может быть Tree -> List, только List -> List.

    The statement uses "Category of..." This defines the scope of the statement. As an example, the Functor Category describes the scope of f * -> g *, i.e., Any functor -> Any functor, e.g., Tree * -> List * or Tree * -> Tree *.

    What a Categorical statement does not specify describes where anything and everything is permitted.

    In this case, inside the functors, * -> * aka a -> b is not specified which means Anything -> Anything including Anything else. As my imagination jumps to Int -> String, it also includes Integer -> Maybe Int, or even Maybe Double -> Either String Int where a :: Maybe Double; b :: Either String Int.

    Итак, утверждение сводится к следующему:

    • область действия функтора :: f a -> g b (т. е. от любого параметризованного типа к любому параметризованному типу)
    • endo + functor :: f a -> f b (т.е. любой параметризованный тип к одному и тому же параметризованному типу) ... иначе говоря,
    • моноид в категории эндофунктора

    Итак, в чем же сила этой конструкции? Чтобы оценить всю динамику, мне нужно было увидеть, что типичные рисунки моноида (одиночный объект с тем, что выглядит как стрелка идентичности, :: single object -> single object), не иллюстрируют, что мне разрешено использовать стрелку, параметризованную с помощью любого числа. значений моноида из объекта типа один, разрешенного в Monoid. Определение эквивалентности endo, ~ identity стрелка игнорирует значение типа функтора, а также тип и значение самого внутреннего, "полезного" уровня. Таким образом, эквивалентность возвращает true в любой ситуации, когда совпадают функциональные типы (например, Nothing -> Just * -> Nothing эквивалентно Just * -> Just * -> Just *, потому что они оба Maybe -> Maybe -> Maybe).

    Sidebar: ~ outside is conceptual, but is the left most symbol in f a. It also describes what "Haskell" reads-in first (big picture); so Type is "outside" in relation to a Type Value. The relationship between layers (a chain of references) in programming is not easy to relate in Category. The Category of Set is used to describe Types (Int, Strings, Maybe Int etc.) which includes the Category of Functor (parameterized Types). The reference chain: Functor Type, Functor values (elements of that Functor's set, e.g., Nothing, Just), and in turn, everything else each functor value points to. In Category the relationship is described differently, e.g., return :: a -> m a is considered a natural transformation from one Functor to another Functor, different from anything mentioned thus far.

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

    • снаружи он выглядит как единый объект (например, :: List); статический
    • but inside, permits a lot of dynamics
      • any number of values of the same type (e.g., Empty | ~NonEmpty) as fodder to functions of any arity. The tensor product will reduce any number of inputs to a single value... for the external layer (~fold that says nothing about the payload)
      • бесконечный диапазон и типа и значений для самого внутреннего слоя

    В Haskell важно уточнить применимость оператора. Мощность и универсальность этой конструкции не имеет абсолютно ничего общего с монадой как таковой. Другими словами, конструкция не зависит от того, что делает монаду уникальной.

    Когда вы пытаетесь понять, нужно ли создавать код с общим контекстом для поддержки вычислений, которые зависят друг от друга, или вычислений, которые могут выполняться параллельно, это печально известное утверждение, со всем его описанием, не является контрастом между выбором Аппликатив, стрелки и монады, а скорее описание того, насколько они одинаковы. Для рассматриваемого решения утверждение спорно.

    Это часто понимают неправильно. Далее в заявлении join :: m (m a) -> m a описывается как тензорное произведение моноидального эндофунктора. Однако он не формулирует, как в контексте этого утверждения также мог быть выбран (<*>). Это действительно пример шести / полдюжины. Логика объединения значений абсолютно одинакова; один и тот же ввод генерирует одинаковый вывод для каждого (в отличие от моноидов Sum и Product для Int, потому что они генерируют разные результаты при объединении Ints).

    Итак, резюмируем: моноид в категории эндофункторов описывает:

       ~t :: m * -> m * -> m *
       and a neutral value for m *
    

    (<*>) и (>>=) оба обеспечивают одновременный доступ к двум значениям m для вычисления единственного возвращаемого значения. Логика, используемая для вычисления возвращаемого значения, точно такая же. Если бы не разные формы параметризируемых ими функций (f :: a -> b по сравнению с k :: a -> m b) и положение параметра с одинаковым типом возвращаемого значения вычисления (т.е. a -> b -> b по сравнению с b -> a -> b для каждого соответственно), я подозреваю, что мы могли бы параметризовать моноидальная логика, тензорное произведение, для повторного использования в обоих определениях. В качестве упражнения, чтобы понять суть, попробуйте реализовать ~t, и вы получите (<*>) и (>>=) в зависимости от того, как вы решите определить его forall a b.

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

    В заключение, по моему собственному опыту, печально известная цитата Мак Лейна предоставила мне отличный мем «goto», ориентир, на который я мог ссылаться при навигации по категориям, чтобы лучше понять идиомы, используемые в Haskell. Ему удается охватить объем мощных вычислительных мощностей, которые прекрасно доступны в Haskell.

    Однако есть ирония в том, что я сначала неправильно понял применимость утверждения вне монады и то, что, надеюсь, передал здесь. Все, что он описывает, оказывается похожим между Applicative и Monads (и Arrows среди других). Но в нем не говорится о небольшом, но полезном различии между ними.

    - E

    person Edmund's Echo    schedule 20.04.2018

    Примечание. Нет, это неправда. В какой-то момент был комментарий к этому ответу от самого Дэна Пипони, в котором говорилось, что причина и следствие здесь были прямо противоположными, что он написал свою статью в ответ на шутку Джеймса Айри. Но, похоже, он был удален, возможно, каким-то навязчивым уборщиком.

    Ниже мой первоначальный ответ.


    Вполне возможно, что Ири прочитал От моноидов к монадам, сообщение, в котором Дэн Пипони (sigfpe) извлекает монады из моноидов в Haskell, с подробным обсуждением теории категорий и явным упоминанием «категории эндофункторов на Hask". В любом случае, любой, кто задается вопросом, что значит для монады быть моноидом в категории эндофункторов, может извлечь пользу из прочтения этого вывода.

    person hobbs    schedule 16.09.2015
    comment
    Возможно, какой-нибудь навязчивый аккуратник - или, как мы с любовью называем их на этом сайте, модератор :-). - person halfer; 19.04.2018