A monad is just a monoid in the category of endofunctors, what's the problem?

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

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

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

 Don Stewart06 окт. 2010 г., 17:27
Смотрите "Категории для рабочего математика"
 Dmitry22 сент. 2016 г., 05:38
ммм, я потратил больше года на размышления о Haskell, и до сих пор не могу с уверенностью понять, что такое функтор (это функциональный объект? объект, который вы можете отобразить? функция, принимающая a и возвращающая M a? двоичная функция, принимающая и возвращая M a? Как вы можете отобразить функцию, если у нее нет элементов для итерации ...) Не говоря уже о том, что такое endofunctor. Я понимаю, что fmap позволяет применять функцию к объекту в штучной упаковке, а >> = позволяет вставлять объект M в штучной упаковке в функцию a -> M a, но что теперь?
 Ben Ford01 авг. 2013 г., 13:09
Я хотел бы добавить этот отличный пост в блоге здесь:stephendiehl.com/posts/monads.html Он не дает прямого ответа на вопрос, но, по моему мнению, Стивен великолепно связывает категории и монады в Хаскеле. Если вы прочитали приведенные выше ответы - это должно помочь объединить два взгляда на это.
 michid09 янв. 2018 г., 17:08
Посмотрите блестящую серию лекций Бартоша МилевскогоТеория категорий для программистов для полной истории. Повсюду в этом Bartosz устанавливают необходимые предпосылки в теории категорий, всегда ссылаясь на Haskell. Последняя часть на самом деле называетсяМоноид в категории эндофункторов и полностью отвечает на вопрос.
 Matthijs29 окт. 2016 г., 11:43
@Dmitry Aфунктор является функцией между категориями, с некоторыми ограничениями, чтобы быть хорошо себя вести. Endofunctor в категории C - это просто функтор от C до самого себя.Data.Functor это класс типов для эндофункторов наКатегория Hask, Поскольку категория состоит из объектов и морфизмов, функтору необходимо отобразить оба. Для экземпляра f объекта Data.Functor карта объектов (типы haskell) - это сама f, а карта морфизмов (функции haskell) - fmap.
 user432277923 июн. 2015 г., 02:04
Точнее, «Для любой категории C категория [C, C] ее эндофункторов имеет моноидальную структуру, индуцированную композицией. Моноидный объект в [C, C] является монадой на C.» - из en.wikipedia.org/wiki/Monoid_%28category_theory%29. См. En.wikipedia.org/wiki/Monad_%28category_theory%29 для определения монады в теории категорий.
 Dmitri Zaitsev29 нояб. 2016 г., 17:48
Смотрите здесь для точного, но человеческого объяснения:stackoverflow.com/questions/2704652/...
 Evi1M4chine03 мар. 2013 г., 17:29
На самом деле, действительно понимаю эту цитатусделал помогите мне понять монады в более глубоком смысле, а также моноиды и функторы. Это только требует, чтобы вы знали другие понятия, которые выдолжен знать в любом случае, чтобы действительно понять эти концепции. И когда вы это делаете, это приятно подводит концепцию к единой ментальной точке. Так что игнорируйте глупые неконструктивные комментарии выше. Все, что нужно, этоправильный объяснение этих понятий, прежде чем читать эту цитату. Тогда это не совсем то, что нужно сказать. Это вся шутка за этим. (Люди не знают этих понятий.)
 starblue07 окт. 2010 г., 20:00
Вам не нужно понимать это, чтобы использовать монады в Haskell. С практической точки зрения они просто умный способ обойти «состояние» через какую-то подземную сантехнику.

Ответы на вопрос(5)

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

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

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

 halfer19 апр. 2018 г., 19:30
«Возможно, каким-то навязчивым тидиром» - или, как мы наивно ссылаемся на них на этом сайте, модератором:-).

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

{-# LANGUAGE RankNTypes, TypeOperators #-}

import Control.Monad (join)

Из этих,RankNTypes это единственный, который абсолютно необходим для ниже.Я однажды написал объяснениеRankNTypes что некоторые люди считают полезнымтак что я буду ссылаться на это.

квотированиеОтличный ответ Тома Крокетта, у нас есть:

Монада это ...Эндофунктор,T: X -> XЕстественная трансформация,μ: T × T -> T, где× означает функторную композициюЕстественная трансформация,η: I -> T, гдеI это личность endofunctor на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 является endofunctor в том, что люди называют «категория Hask», чьи объекты являются типами 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) hCompose f Identity ~= fCompose 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.
 dfeuer20 мар. 2015 г., 16:53
вNatural новый тип, я не могу понять, что(Functor f, Functor g) ограничение делает. Могли бы вы объяснить?
 Lambda Fairy21 мар. 2015 г., 09:03
@ LuisCasillas Я удалил этиFunctor ограничения, так как они не кажутся необходимыми. Если вы не согласны, добавьте их обратно.
 Luis Casillas20 мар. 2015 г., 19:15
@dfeuer Ничего существенного не делает.
 tksfz01 апр. 2015 г., 23:54
Можете ли вы уточнить, что формально означает, что произведение функторов следует рассматривать как композицию? В частности, каковы морфизмы проекции для композиции функторов? Я предполагаю, что произведение определено только для функтора F против самого себя, F x F и только когдаjoin определено. И этоjoin это морфизм проекции. Но я не уверен.
Решение Вопроса

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

Оригинальная цитата из Saunders Mac Lane вКатегории для рабочего математика, один из основополагающих текстов теории категорий.Вот это в контексте, что, вероятно, лучшее место, чтобы узнать, что именно это значит.

Но я сделаю удар. Оригинальное предложение таково:

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

X вот категория. Эндофункторы - это функторы от категории к себе (которая обычновсе Functorс точки зрения функциональных программистов, поскольку они в основном имеют дело только с одной категорией; категория типов - но я отвлекся). Но вы можете представить себе другую категорию, которая является категориейX". Это категория, в которой объекты являются эндофункторами, а морфизмы - естественными преобразованиями.

И из этих эндофункторов, некоторые из них могут быть монадами. Какие из них монады? Именно те, которыемоноидальная в определенном смысле. Вместо того, чтобы описать точное отображение от монад к моноидам (поскольку Mac Lane делает это намного лучше, чем я мог надеяться), я просто добавлю их соответствующие определения рядом и позволю вам сравнить:

Моноид это ...Множество,SОперация,•: S × S → SЭлементS, e: 1 → S... удовлетворяя этим законам:(a • b) • c = a • (b • c), для всехa, b а такжеc вSе • а = а • е = а, для всехa вSМонада это ...Эндофунктор,T: X → X (в Хаскеле, конструктор типа* -> * сFunctor пример)Естественная трансформация,μ: T × T → T, где× означает функторную композицию (μ известен какjoin в Хаскеле)Естественная трансформация,η: I → T, гдеI это личность endofunctor наX (η известен какreturn в Хаскеле)... удовлетворяя этим законам:μ ∘ Tμ = μ ∘ μTμ ∘ Tη = μ ∘ ηT = 1 (идентичность естественной трансформации)

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

 Tom Crockett14 апр. 2015 г., 06:12
@CMCDragonkai Один из способов понять более простую теоретико-множественную идею моноида в теории категорий - сказать, что это любой моноидный объект в моноидальной категории.Задавать, как обсуждалось выше ...
 Lifu Huang24 сент. 2016 г., 17:13
Привет, @TomCrockett. Вы упомянули в комментарии, что «для любого элемента e из S существует ровно одна функция f: 1 -> S, где 1 - любой одноэлементный набор». Зачем? Я могу понять, что для любого элемента e из S существует ровно одна функция (постоянная функция), отображающая из S в {e}, но кажется, что вы упомянули, что это наоборот. IMO, может быть несколько отображений функций из {e} в S. Не могли бы вы сказать мне, где я не прав? Спасибо!
 Tom Crockett28 сент. 2016 г., 19:22
@LifuHuang Да, это правильно. Интуиция позади обозначенияF(f) это функторF: C → D это карта междукатегориии как таковые отображает оба объекта вC (Р (А)), а также морфизмы вC (Р (е)).
 Tahir Hassan01 нояб. 2012 г., 12:41
Меня смущает ваше определение моноида, а именно: «ЭлементS, E: 1 -> S". Такe является элементомS, но тогда вы определяете это какE: 1 -> S" Который означает, чтоe это функция с доменом1 и кодоменS, Что это значит?
 Tom Crockett14 апр. 2015 г., 06:33
 Tunococ20 июл. 2016 г., 05:20
Я знаю, что этот ответ старый, но меня беспокоит, что этот популярный ответ дает неверный контекст и неправильное определение моноида. В книге Мак Лэйна моноид может жить в любой категории. И в указанной категории эндофункторов не требуется косить, чтобы соответствовать его определению моноида. Его моноидом в категории наборов станет ваш (обычный) моноид. Пожалуйста, проверьте источник.
 CMCDragonkai14 апр. 2015 г., 02:30
@ TomCrockett спасибо! Просто для упрощения, моноидальные категории являются категориальным представлением классического определения моноидов?
 mbrig09 февр. 2018 г., 17:39
Я думаю, что я собираюсь прочитать книгу по теории категорий и перечитать этот комментарий и ответы. У меня такое чувство, что над моей головой едут какие-то очень полезные вещи.
 Roman A. Taycher06 окт. 2010 г., 15:39
спасибо за объяснение и за статью «Краткая, неполная и в основном неправильная история языков программирования». Я думал, что это может быть оттуда. Поистине один из величайших юморов программирования.
 Ivan Gozali16 нояб. 2014 г., 20:35
Я в замешательстве, так как моя (неправильная) интуиция говорит, что монады более абстрактны, чем моноиды (поскольку они имеют дело с эндофункторами и преобразованиями, которые кажутся более абстрактными, чем множества и элементы). Но из приведенного выше объяснения (что, очевидно, правильно), монады являются «конкретизацией» моноидов? Очевидно, я этого не понимаю.
 Tom Crockett13 апр. 2015 г., 22:05
@CMCDragonkai, чтобы ответить на ваш второй вопрос, нет, не все объекты в моноидальной категории обязательно являются моноидами. Например,Задавать является моноидальной категорией, как мы наблюдали выше, но возьмем пустое множество ∅ ... оно не может быть моноидальным, потому что не может быть морфизма единицη: 1 → ∅, Напомним, что в случаеЗадаватьморфизмы - это функции, а единичный объект («I») - это любой одноэлементный набор.
 CMCDragonkai13 апр. 2015 г., 12:29
Категория эндофункторов называется «моноидальной категорией».Делает ли это категорию эндофункторов?сам тоже моноид? Если так, моноидальные категории всегда содержат моноиды как объекты? Всегда ли моноиды содержатся в какой-то моноидальной категории?
 Owen03 янв. 2012 г., 04:53
Я думаю, что Monoid Maclane, о котором идет речь, является немного более общим, чем тот, который вы описали, потому что «множество» - это некоторый объект в некоторой категории, а операции - это морфизм, не обязательно определенный в терминах элементов. И в данном конкретном случае это категория эндофункторов, где произведение двух объектов (где объекты являются функторами) вместо того, чтобы быть декартовым произведением, это состав функторов ... который выглядит довольно по-разному, хотя у меня нет хорошее интуитивное понимание того, что это значит.
 Lifu Huang26 сент. 2016 г., 04:59
Спасибо, @TomCrockett. И еще один вопрос, потому что у меня нет опыта в теории категорий. Я немного запутался по поводу μ (η (T)) = T = μ (T (η)). Насколько я понимаю, η - это морфизм (или стрелка), указывающий от объекта I к объекту T (ну, конечно, в категории эндофункторов морфизм - это естественная трансформация, как вы упоминали). Тогда что значит η (T)? что еще больше озадачивает меня, так это значение T (η), поскольку T - это объект, а η - морфизм. Большое спасибо!
 Jonathan Sterling20 окт. 2010 г., 04:47
Это фантастическое объяснение, но у меня есть один вопрос. Я получаю, что моноидальный продукт имеет типS × S -> S, но что является еще одним примером того, что× находится вне контекста функторной композиции? Например, может быть умножение или сложение в натуральных числах; что такое× в данном контексте?
 JustAskin05 сент. 2016 г., 20:33
«И из этих эндофункторов, некоторые из них могут быть монадами». Монада не является эндофункцией, которая простопроисходит удовлетворить дополнительные свойства. Монада является эндофункторомоснащен две естественные трансформации. Это в том же смысле, что группа не является моноидом, которыйпроисходит иметь инверсии для каждого элемента, это моноидоснащен дополнительная унарная операция, которая удовлетворяет обратному закону.
 Tom Crockett06 сент. 2016 г., 02:12
@ barron, если вы действительно хотите быть педантичным, вы можете пойти дальше и сказать, что моноид оборудован одинарной операцией, котораяпросто случается удовлетворять обратному закону тоже не группа. Это также должно бытьоснащен доказательством эта операция удовлетворяет обратному закону! Весь вопрос в том, какие реквизиты являются частью языка объекта против метаязыка.
 Tom Crockett25 сент. 2016 г., 01:42
@LifuHuang вы правы, это было неправильно сформулировано. Я имел в виду только предыдущее предложение: «элементы любого множестваS находятся в непосредственном соответствии с функциями из любого одноэлементного набораSто есть существует биекция междуS а также1 → S, Очевидная биекция берет любой данныйs ∈ S в{(e, s)}.
 Tom Crockett27 сент. 2016 г., 00:41
@LifuHuang Вы можете прочитать здесь, что обозначенияηT а такжеTη имею в виду:en.wikipedia.org/wiki/... ... ваш вопрос заставил меня понять, что мое описание законов монады было непоследовательным, поэтому я переписал его. К сожалению, синтаксическое сходство с моноидными законами уже не так очевидно; Мне нужно будет придумать, как это прояснить.
 Lifu Huang28 сент. 2016 г., 02:41
Ну, это действительно не так просто. В любом случае, спасибо, это лучший ответ относительно монады, которую я когда-либо читал :)
 Lifu Huang28 сент. 2016 г., 11:51
Благодарю. Так что $ \ mu \ circ F (\ mu) = \ mu \ circ \ mu $ на этой странице - это то же самое, что $ \ mu \ circ T \ mu = \ mu \ circ \ muT $ в вашем ответе, верно? $ F (\ mu) $ выглядит для меня очень странно, это еще одна стандартная запись?
 Lifu Huang29 сент. 2016 г., 01:40
Понимаю. Спасибо! Я действительно должен тебе сто голосов :)
 Tom Crockett25 апр. 2014 г., 20:57
@ YetAnotherGeek Да.
 Tom Crockett28 сент. 2016 г., 10:34
@LifuHuang Лучший способ увидеть, как это определение относится к Haskell, - это заметить, чтоμ являетсяjoin в Хаскеле иm >>= f = join (fmap f m), Законы монады Хаскелла являются повторением этих законов, но с точки зрения>>=, Смотрите эту страницу для более подробной информации:wiki.haskell.org/Category_theory/Monads.
 Tom Crockett02 нояб. 2012 г., 00:43
@TahirHassan Таким образом, хотя стрелки от конечного объекта к объекту S не являются «тем же самым», что и элементы S, ониизоморфный к его элементам, что касается теории категорий так же хорошо.
 Lifu Huang28 сент. 2016 г., 09:06
Ой, еще один вопрос. Благодаря вашему подробному объяснению теперь я понял определение монады в вашем посте. Но когда я вернулся, чтобы заново изучить определение монады в языках программирования. Я нашел свод законов монады (wiki.haskell.org/Monad_laws) выглядит не так, как в вашем посте. Не могли бы вы объяснить, как эти два набора законов соответствуют друг другу? Какова математическая интерпретация «связать»? Еще раз спасибо.
 CMCDragonkai14 апр. 2015 г., 06:21
Я также запутался в эквивалентности между ETA-функциейη : I → T иreturn функция в Haskell. Этоreturn функция должна быть эта? Я не совсем вижу отношения. Это предназначено для определения Т как заостренного объекта?
 Tom Crockett28 сент. 2016 г., 19:35
@LifuHuang После написания этих двух комментариев я понял, что на самом деле не отвечал на ваш вопрос, потому что здесь уловка в том, что мы применяемF не только к морфизму, но и к естественной трансформации. Интуиция в отношении Хаскелла состоит в том, что естественные преобразования являются полиморфными функциями. Например,id :: forall a. a -> a это не просто морфизм вHask но на самом деле весьсемья морфизмов - естественная трансформация! Ноfmap id :: forall a. Functor f => f a -> f a проверки типов просто отлично, и это именно то, что обозначениеF (μ) о том, когдаμ это естественная трансформация.
 Evi1M4chine28 июл. 2014 г., 02:56
Хороший способ сказать это в одном предложении:Монады - это просто каналы («цепочечных») «контейнерных» (контентных) преобразований.   Считайте «pipe of (chained)» как «monoidal», «container» как «category» и «… transformation» как «функторы», и у вас есть предложение, эквивалентное цитируемому.По сути, монады - это (не) сборочные линии. ^^
 Tom Crockett13 апр. 2015 г., 21:56
@CMCDragonkai На ваш первый вопрос, цитируястраница википедииЕсть общее понятие моноидного объекта в моноидальной категории, которое обобщает обычное понятие моноида.В частности, строгая моноидальная категория может рассматриваться как моноидальный объект в категории категорий Cat (оснащенной моноидальной структурой, индуцированной декартовым произведением)."
 Tom Crockett02 нояб. 2012 г., 00:22
@TahirHassan - В общности теории категорий мы имеем дело с непрозрачными «объектами» вместо множеств, и поэтому нет априорного понятия «элементы». Но если вы думаете о категорииЗадавать где объекты - наборы, а стрелки - функции, элементы любого набора S находятся в взаимно однозначном соответствии с функциями из любого одноэлементного элемента, установленного в S. То есть для любого элементаe изSесть ровно одна функцияF: 1 -> S, где1 любой одноэлементный набор ... (продолжение)
 Tom Crockett27 сент. 2016 г., 20:53
@LifuHuang да, вы указали точную трудность! Я подозреваю, что нет никаких ярлыков, и удовлетворительное объяснение требует введения категориального понятия моноида и показа, как это специализируется наЗадавать а такжеКонец соответственно.
 Tom Crockett20 окт. 2010 г., 10:19
@ Джонатан: В классической формулировке моноида,× означает декартово произведение множеств. Вы можете прочитать больше об этом здесь:en.wikipedia.org/wiki/Cartesian_product, но основная идея заключается в том, что элементS × T это пара(с, т), гдеs ∈ S а такжеt ∈ T, Итак, подпись моноидального произведения•: S × S -> S в этом контексте просто означает функцию, которая принимает 2 элементаS в качестве входных данных и производит другой элементS в качестве выхода.
 Tom Crockett14 апр. 2015 г., 06:08
@CMCDragonkai хорошо, теоретико-категоричная версия является обобщением идеи, которая позволяет нам классифицировать больше вещей как моноиды, чем теоретико-множественное определение. Это связано с тем, что законы ассоциативности и тождества задаются в терминах естественных изоморфизмов, а не простых равенств (это равенства "вплоть до" естественного изоморфизма).
 Tom Crockett14 апр. 2015 г., 06:16
@CMCDragonkai другой, более простой способ заключается в следующем: моноид в теоретико-множественном смысле - это (малая) категория только с одним объектом. Просто представьте себе композицию морфизмов как операцию моноида, морфизм тождественности единственного объекта как единицы моноида и любой другой (эндо-) морфизм как еще один элемент моноида
 Tom Crockett14 апр. 2015 г., 06:30
@CMCDragonkai Да,return это η. Помните, что η - это естественное преобразование между эндофункторами, поэтому оно параметризуется объектом (в случаеHask, тип); его подпись в Хаскеле будет что-то вродеη :: I a → T a. I это личность endofunctor, поэтому мы можем просто написатьη :: a → T a, гдеT Ваш монадический эндофунктор; надеюсь, это напоминает вам оreturn подпись.
 Tom Crockett02 нояб. 2012 г., 00:35
@TahirHassan - Чтобы выразить это на языке Хаскелла, подумайте о том, что еслиS это тип, все, что вы можете сделать при написании функцииf :: () -> S это выбрать какой-то конкретный термин типаS («элемент» этого, если хотите) и вернуть его ... вам не дали никакой реальной информации с аргументом, так что нет способа изменить поведение функции. Такf должна быть постоянной функцией, которая каждый раз возвращает одно и то же.() («Единица») - конечный объект категорииHaskи не случайно, что существует ровно 1 (не расходящаяся) величина, которая населяет его.
 Tom Crockett10 апр. 2015 г., 19:24
@IvanGozali Теория множеств - это одна установка, в которой вы можете определить, что такое моноид; теория категорий - это еще один, более абстрактный контекст. Теоретико-множественное определение моноида выпадает как один частный случай теоретико-категоричного определения (когда рассматриваемая категорияЗадавать) и монадыдругой особый случай (когда категория является категорией эндофункторов над другой категорией). Смотрите приведенные примерыВот для большего количества экземпляров моноидов. Так что моноиды на самом деле являются более абстрактным понятием.
 Tom Crockett28 сент. 2016 г., 19:22
@LifuHuang В Хаскеле, гдеFunctor мы имеем в виду "Endofunctor наHask",Functor карты объектовHask к другим объектам вHask, Поскольку объектыHask являются типами, это просто означает, чтоFunctor примерt может применяться к типуa дать другой типt a... то есть это конструктор типов! И какFunctor примерt отображает функциюf: a -> b к функцииt a -> t b конечно черезfmap.
 Lifu Huang27 сент. 2016 г., 09:39
как общее определение моноида соответствует определению моноида вЗадавать а также тот, вКонец, Поскольку большинство людей, не имеющих опыта в теории категорий, я считаю, не может связать определение здесь (en.wikipedia.org/wiki/Monoid_(category_theory) ) их знакомое определение моноида вЗадавать с точки зрения элементов, не говоря уже об определении моноида вКонец.
 Yet Another Geek25 апр. 2014 г., 17:06
Такµ это присоединиться иη это возвращение, верно? (По крайней мере, в мире Хаскелла)
 Lifu Huang27 сент. 2016 г., 09:32
Еще раз спасибо, @TomCrockett. Я предполагаю, что причина, по которой синтаксическое сходство теперь исчезает, заключается в том, что вы описываете ассоциативность и единицу моноида вЗадавать в терминах «элемент a, b, c», в то время как понятия «элемент» вКонец, Но определение моноида в терминах «элемент a, b, c» является наиболее (и, вероятно, единственным) приемлемым способом для новичков (таких как я). С моей точки зрения, было бы здорово, если бы вы могли, дав определение моноида вЗадавать в терминах «элемент a, b, c» также публикует общее определение моноида в моноидальной категории, а затем объясняет (продолжение)
 CMCDragonkai13 апр. 2015 г., 13:20
Все ли объекты в моноидальной категории являются моноидами? Или некоторые объекты не могут быть моноидами?
 Tom Crockett13 апр. 2015 г., 21:57
@CMCDragonkai «Строгая моноидальная категория - это та, для которой естественные изоморфизмы α, λ и ρ являются тождествами. Каждая моноидальная категория моноидально эквивалентна строгой моноидальной категории».
 JustAskin06 сент. 2016 г., 17:55
@ TomCrockett Да, например ассоциатор / объединитель в моноидальной категории, но я не пытаюсь быть настолько педантичным. Я хочу сказать, что один и тот же endofunctor может (в некоторых случаях) по-разному превращаться в монаду, c.f. экзотические сферы. Иметь endofunctor и сказать "Это монада?" это все равно что иметь коллектор и спрашивать: «Это дифференцируемый коллектор?» где на указанном многообразии может существовать несколько различных недиффеоморфных дифференциальных структур. Фраза «Какие монады?», Для меня, предполагает, что мы заботимся только о существовании дополнительных данных, а не их содержания.
 Tom Crockett02 нояб. 2012 г., 00:26
@TahirHassan 1-элементные наборы сами являются специализациями более общего теоретико-категоричного понятия «терминальные объекты»: терминальный объект - это любой объект категории, для которого есть ровно одна стрелка от любого другого объекта (вы можете проверить, что это верно для 1-элементных наборов вЗадавать). В теории категорий терминальные объекты просто называются1; они уникальны с точностью до изоморфизма, поэтому нет смысла их различать. Так что теперь у нас есть чисто теоретико-категоричное описание «элементовS" для любогоS: они просто стрелки из1 вS!

Я пришел к этому посту, чтобы лучше понять вывод печально известной цитаты из Mac Lane'sТеория категорий для рабочего математика.

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

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

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

endo => любая стрелка или морфизм, который начинается и заканчивается в одном и том же местеfunctor => любая стрелка или морфизм между двумя категориями

(например, в день ото дняTree a -> List b, но в категорииTree -> List)

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

В операторе используется «Категория ...» Это определяет область действия оператора. В качестве примера, категория Functor описывает область действияf * -> g *то естьAny functor -> Any functorнапример,Tree * -> List * или жеTree * -> Tree *.

То, что категорическое утверждение не определяет, описывает, гдевсе и все разрешено.

В этом случае внутри функторов* -> * акаa -> b не указано что означаетAnything -> Anything including Anything else, Поскольку мое воображение переходит на Int -> String, оно также включает в себяInteger -> Maybe Int, или дажеMaybe Double -> Either String Int гдеa :: Maybe Double; b :: Either String Int.

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

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

Итак, где же сила этой конструкции? Чтобы оценить всю динамику, мне нужно было увидеть, что типичные рисунки моноида (единичный объект с чем-то похожим на стрелку,:: single object -> single object), не иллюстрирует, что мне разрешено использовать стрелку, параметризованнуюлюбой номер моноидных значений, изодин type object permitted in Monoid. The endo, ~ identity arrow definition of equivalence игнорируемых the functor's type value and both the type and value of the most inner, "payload" layer. Thus, equivalence returns true in any situation where the functorial types match (e.g., Nothing -> Just * -> Nothing эквивалентноJust * -> Just * -> Just * because they are both 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.

Back to the main thread, all in all, for any defined tensor product and a neutral value, the statement ends up describing an amazingly powerful computational construct born from its paradoxical structure:

on the outside it appears as a single object (e.g., :: List); статическийbut inside, permits a lot of dynamicsany 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)infinite range of и то и другое the type and values for the inner most layer

In Haskell, clarifying the applicability of the statement is important. The power and versatility of this construct, has absolutely nothing to do with a monad как таковой, In other words, the construct does not rely on what makes a monad unique.

When trying to figure out whether to build code with a shared context to support computations that depend on each other, versus computations that can be run in parallel, this infamous statement, with as much as it describes, is not a contrast between the choice of Applicative, Arrows and Monads, but rather is a description of how much they are the same. For the decision at hand, the statement is moot.

This is often misunderstood. The statement goes on to describe join :: m (m a) -> m a as the tensor product for the monoidal endofunctor. However, it does not articulate how, in the context of this statement, (<*>) could also have also been chosen. It truly is a an example of six/half dozen. The logic for combining values are exactly alike; same input generates the same output from each (unlike the Sum and Product monoids for Int because they generate different results when combining Ints).

So, to recap: A monoid in the category of endofunctors describes:

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

(<*>) а также(>>=) both provide simultaneous access to the two m values in order to compute the the single return value. The logic used to compute the return value is exactly the same. If it were not for the different shapes of the functions they parameterize (f :: a -> b противk :: a -> m b) and the position of the parameter with the same return type of the computation (i.e., a -> b -> b противb -> a -> b for each respectively), I suspect we could have parameterized the monoidal logic, the tensor product, for reuse in both definitions. As an exercise to make the point, try and implement ~t, and you end up with (<*>) а также(>>=) depending on how you decide to define it forall a b.

If my last point is at minimum conceptually true, it then explains the precise, and only computational difference between Applicative and Monad: the functions they parameterize. In other words, the difference is внешний to the implementation of these type classes.

In conclusion, in my own experience, Mac Lane's infamous quote provided a great "goto" meme, a guidepost for me to reference while navigating my way through Category to better understand the idioms used in Haskell. It succeeds at capturing the scope of a powerful computing capacity made wonderfully accessible in Haskell.

However, there is irony in how I first misunderstood the statement's applicability outside of the monad, and what I hope conveyed here. Everything that it describes turns out to be what is similar between Applicative and Monads (and Arrows among others). What it doesn't say is precisely the small but useful distinction between them.

- E

Интуитивно, я думаю, что сказочный математический словарь говорит о том, что:

Monoid

A моноид это набор объектов и метод их объединения. Хорошо известны моноиды:

числа, которые вы можете добавитьсписки, которые вы можете объединитьустанавливает вы можете объединение

Есть и более сложные примеры.

В дальнейшем,каждый моноид имеетидентичностьЭто тот элемент "no-op", который не имеет эффекта, когда вы комбинируете его с чем-то другим:

0 + 7== 7 + 0== 7[] ++ [1,2,3]== [1,2,3] ++ []== [1,2,3]{}союз {яблоко}== {яблоко}союз {}== {яблоко}

Наконец, моноид должен бытьассоциативный, (вы можете уменьшить длинную строку комбинаций в любом случае, если только вы не измените порядок объектов слева направо). Дополнение в порядке ((5 + 3) +1 == 5+ (3+ 1)), но вычитание не ((5-3) -1! = 5- (3-1)).

монада

Теперь давайте рассмотрим особый вид множества и особый способ объединения объектов.

Объекты

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

Вычислить 0 или более результатовОбъедините эти результаты в один ответ как-нибудь.

Примеры:

1 -> [1] (просто оберните ввод)1 -> [] (отменить ввод, обернуть небытие в списке)1 -> [2] (добавьте 1 к входу и оберните результат)3 -> [4, 6] (добавьте 1 к входу, умножьте ввод на 2 и обернитенесколько результатов)Объединение объектов

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

1 -> [1] -> [[1]] (дважды оберните вход)1 -> [] -> [] (отменить ввод, обернуть пустоту в списке, дважды)1 -> [2] -> [UH-OH! ] (мы не можем «добавить 1» в список! »)3 -> [4, 6] -> [UH-OH! ] (мы не можем добавить 1 список!)

Не слишком углубляясь в теорию типов, дело в том, что вы можете объединить два целых числа, чтобы получить целое число, но вы не всегда можете составить две функции и получить функцию одного типа. (Функции с типома -> а будет сочинять, ноa-> [a] не будет.)

Итак, давайте определим другой способ объединения функций. Когда мы объединяем две из этих функций, мы не хотим «оборачивать» результаты.

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

Вычислите «результаты» из F, но не объединяйте их.Вычислите результаты применения G к каждому из результатов F по отдельности, получая коллекцию результатов.Сгладьте 2-уровневую коллекцию и объедините все результаты.

Возвращаясь к нашим примерам, давайте объединим (свяжем) функцию с самой собой, используя этот новый способ «связывания» функций:

1 -> [1] -> [1] (дважды обернуть вход)1 -> [] -> [] (отменить ввод, обернуть пустоту в списке, дважды)1 -> [2] -> [3] (добавьте 1, затем снова добавьте 1 и оберните результат.)3 -> [4,6] -> [5,8,7,12] (добавьте 1 к вводу, а также умножьте ввод на 2, сохраняя оба результата, затем сделайте все снова для обоих результатов, а затем оберните окончательный вариант результаты в списке.)

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

Связывая все это вместе,

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

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

Я немного расстроился с определениями в надежде донести основную идею до интуитивно понятной.

Я немного упростил ситуацию, настаивая на том, что наша монада работает с функциями типаa -> [a], На самом деле, монады работают над функциями типаа -> м б, но обобщение - это своего рода техническая деталь, которая не является главной идеей.

 Adam Barnes04 февр. 2019 г., 01:48
Это фантастика - это единственное объяснение, которое я понял достаточно хорошо, чтобы иметь возможность объяснить это кому-то еще ... Но я все еще не понимаю, почему это ценный способ думать о чем-либо. :(
 Tom Crockett10 дек. 2011 г., 20:46
Разумеется, если вы ограничиваете монаду только одним типом, то есть, если вы разрешаете только стрелки Клейсли в формеa -> [a]это будет моноид (потому что вы будете сокращать категорию Клейсли до одного объекта, а любая категория только одного объекта по определению является моноидом!), но это не будет отражать всю общность монады.
 sjas02 дек. 2013 г., 20:20
Это лучшее и наиболее вежливое объяснение монад и их математического фона моноидов, с которыми я столкнулся буквально за несколько недель. Это то, что должно быть напечатано в каждой книге на Haskell, когда дело доходит до монад, руками вниз. UPVOTE! Может быть, в дальнейшем получу информацию, что монады реализованы как параметризованные экземпляры классов типов, которые помещают в сообщение все, что помещено в них в haskell. (По крайней мере, так я их уже понял. Поправь меня, если я ошибаюсь.haskell.org/haskellwiki/What_a_Monad_is_not )
 Evi1M4chine03 мар. 2013 г., 18:34
На последнем замечании, это помогает помнить, что a -> [a] - это просто -> [] a. ([] тоже просто конструктор типов.) И поэтому его можно не только рассматривать как -> m b, но [] действительно является экземпляром класса Monad.
 Tom Crockett10 дек. 2011 г., 20:35
Это хорошее объяснение того, как каждая монада представляет собойкатегория (Клейсли категория это то, что вы демонстрируете - есть также категория Эйленберга-Мура). Но из-за того, что вы не можете сочинятьлюбой две стрелы Клейслиa -> [b] а такжеc -> [d] (Вы можете сделать это только еслиb = c), это не совсем описывает моноид. На самом деле вы описали операцию выравнивания, а не композицию функций, которая является «оператором моноида».
 AsymLabs05 нояб. 2015 г., 22:20
Просто выдающийся! Прошло некоторое время с тех пор, как он был написан, и вы дали превосходную концептуальную иллюстрацию моноидов, идентификаторов и монад, но можете ли вы добавить абзац, чтобы связать все это вместе, чтобы концептуально проиллюстрировать, как они сочетаются в общей теории категорий - или у вас есть ссылки?

Ваш ответ на вопрос