O monadă este doar un monoid în categoria de endofunctors, ceea ce's problema?

Primul care a spus următoarele?

O monadă este doar un monoid în categoria de endofunctors, ceea ce's problema?

Și pe o mai puțin important să rețineți, acest lucru este adevărat și dacă așa ar putea oferi o explicație (sperăm, una care poate fi înțeles de către cineva care nu't au mult Haskell experiență)?

Comentarii la întrebare (9)
Soluția

Special frazare este de James Fumez, din foarte distractiv Scurtă, Incompletă și cea mai mare parte Greșită Istoria limbajelor de Programare, în care el ficțional atribute la Philip Wadler.

Citatul original este de la Saunders Mac Lane în Categorii pentru Lucru Matematician, unul din textele de bază din Teoria Categorie. Aici este în context, care este, probabil, cel mai bun loc pentru a ști exact ce înseamnă.

Dar, am'll ia o lovitură de cuțit. Sentința inițială este aceasta:

Toate-a spus, o monadă în X este doar un monoid în categoria de endofunctors de X, cu produs × înlocuit cu o compoziție de endofunctors și unitatea set de identitate endofunctor.

X aici este o categorie. Endofunctors sunt functori dintr-o categorie în sine (care este, de obicei, toate `Functor este pe cât de funcțional programatori sunt în cauză, deoarece acestea're cea mai mare parte de-a face doar cu o singură categorie; categoria de tipuri - dar am deviat de la subiect). Dar ai putea imagina o altă categorie care este categoria de "endofunctors pe X". Aceasta este o categorie în care obiectele sunt endofunctors și morfisme sunt naturale transformări.

Și de cei endofunctors, unele dintre ele ar putea fi monadele. Care sunt cele monadele? Exact cei care sunt monoidal într-un anumit sens. În loc de a scrie exact cartografiere de la monadele să monoids (din Mac Lane face asta mult mai bine decât aș putea spera să), I'll pune definiții lor alături și vă permite să comparați:

Un monoid este...

  • Un set, S
  • O operație, • : S × S → S
  • Un element de S, e : 1 → S

...satisface aceste legi:

  • (a • b) • c = a • (b • c), pentru toate o, b și c in S
  • e • o = o • e = o, pentru toate o in S

O monadă este...

  • Un endofunctor, T : X → X (în Haskell, un constructor de tip de tip * -> * "cu o" Functor exemplu)
  • Un transformării naturale, μ : T × T → T, unde × mijloace functor compoziție (μ este cunoscut ca join în Haskell)
  • Un transformării naturale, η : I → T, unde I este identitatea endofunctor pe X (η este cunoscut ca reveni în Haskell)

...satisface aceste legi:

  • μ ∘ Tµ = μ ∘ µT
  • μ ∘ Tn = μ ∘ nT = 1 (identitatea naturale de transformare)

Cu un pic de cruciș s-ar putea fi capabil de a vedea că ambele definiții sunt instanțe de același abstract.

Comentarii (46)

Intuitiv, cred că ceea ce fantezie matematica vocabular spune este că:

Monoid

O monoid este un set de obiecte, și o metodă de a le combina. Bine cunoscut monoids sunt:

  • puteți adăuga numere
  • liste puteți înlănțui
  • seturi puteți uniunii

Acolo sunt mult mai complexe exemple de asemenea.

Mai mult, fiecare monoid are un identitatea**, care este ca "nu-op" element care nu are nici un efect atunci când se combina cu altceva:

  • 0 + 7 == 7 + 0 == 7
  • [] ++ [1,2,3] == [1,2,3] ++ [] == [1,2,3]
  • {} uniunii {mar} == {mar} uniunea {} == {apple}

În cele din urmă, un monoid trebuie să fie asociative. (puteți reduce un lung șir de combinații oricum doriți, atâta timp cât nu't schimba de la stânga la dreapta-comanda de obiecte) Plus este OK ((5+3)+1 == 5+(3+1)), dar scăderea nu este't ((5-3)-1 != 5-(3-1)).

Monadă

Acum, las's ia în considerare un tip special de set și un mod special de a combina obiecte.

Obiecte

Să presupunem că setul contine obiecte de un tip special: funcții. Și aceste funcții au un interesant semnătura: Ei don't transporta numere numere sau siruri de caractere de la siruri de caractere. În schimb, fiecare funcție poartă un număr cu o listă de numere într-un proces în două etape.

  1. Calcula 0 sau mai multe rezultate
  2. Combina aceste rezultate, óntr-un singur răspuns într-un fel.

Exemple:

  • 1 -> [1] (doar folie de intrare)
  • 1 -> [] (aruncați de intrare, înfășurați în neant într-o listă)
  • 1 -> [2] (adăugați 1 la intrare, și înfășurați rezultat)
  • 3 -> [4, 6] (adăugați 1 la intrare, și să se înmulțească de intrare de 2, și înfășurați mai multe rezultate)

Combinarea Obiectelor

De asemenea, modul nostru de a combina funcțiile speciale. Un mod simplu de a combina funcția este compozitie: Las's ia exemplele noastre de mai sus, și compune fiecare funcție cu sine:

  • 1 -> [1] -> [[1]] (folie de intrare, de două ori)
  • 1 -> [] -> [] (aruncați de intrare, înfășurați în neant într-o listă, de două ori)
  • 1 -> [2] -> [ UH-OH! ] (putem't "se adaugă 1" pentru o listă!")
  • 3 -> [4, 6] -> [ UH-OH! ] (putem't se adauga 1 o listă!)

Fără a intra prea mult în tipul de teorie, ideea este că puteți combina două numere întregi pentru a obține un număr întreg, dar poate't întotdeauna compune două funcții și a obține o funcție de același tip. (Funcții de tip a -> un va compune, dar a-> [a] a câștigat't.)

Deci, să's a defini un mod diferit de combinare a funcțiilor. Când ne-am combina aceste două funcții, nu ne't vreau să "dublu-wrap" rezultatele.

Aici este ceea ce facem. Atunci când vrem să combine două funcții F și G, urmăm acest proces (numit obligatoriu):

  1. Calcula "rezultatele" de la F, dar don't să le combine.
  2. Calcula rezultate din aplicarea G pentru fiecare dintre F's rezultatele separat, obținându-se o colecție de colecție de rezultate.
  3. Aplatiza 2-nivel de colectare și de a combina toate rezultatele.

Înapoi la exemplele noastre, să's combina (bind) o funcție cu sine, folosind acest nou mod de "obligatoriu" funcții:

  • 1 -> [1] -> [1] (folie de intrare, de două ori)
  • 1 -> [] -> [] (aruncați de intrare, înfășurați în neant într-o listă, de două ori)
  • 1 -> [2] -> [3] (adăugați 1, apoi se adaugă 1 din nou, și înfășurați rezultatul.)
  • 3 -> [4,6] -> [5,8,7,12] (adăugați 1 la intrare, și de a multiplica, de asemenea, de intrare de 2, păstrând ambele rezultate, apoi face totul din nou pentru ambele rezultate, și apoi înfășurați rezultatele finale într-o listă.)

Acest mod mai sofisticat de a combina funcțiile de e asociative (urmare din funcția de compoziție este asociativă când nu't face fantezie ambalaj chestii).

Legându-l toate împreună,

  • o monadă este o structură care definește un mod de a combina (rezultatele) funcții,
  • în mod analog cu modul în care un monoid este o structură care definește un mod de a combina obiecte,
  • în cazul în care metoda de combinare este asociativă,
  • și în cazul în care există o special 'Nu po', care pot fi combinate cu orice ceva pentru a duce la ceva neschimbată.

Note

Există o mulțime de moduri de a "folie de" rezultate. Puteți face o listă, sau un set, sau aruncați toate, dar primul rezultat, în timp ce observând dacă nu există nici un rezultat, atașați un ataș de stat, print-un mesaj de jurnal, etc, etc.

Am'am jucat un pic libere cu definițiile în speranța de a obține ideea esențială pe intuitiv.

Am'am simplificat un pic lucrurile, insistând că ne monadă funcționează pe funcții de tip a -> [o]. În fapt, monadele muncă pe funcții de tip a -> m b, dar generalizarea este un fel de detaliu tehnic pe care nu - 't principalele insight.

Comentarii (6)

În primul rând, extensii și bibliotecile pe care le're de gând să utilizați:

{-# LANGUAGE RankNTypes, TypeOperators #-}

import Control.Monad (join)

Dintre acestea, RankNTypes este singurul care's, absolut esențial pentru de mai jos. Am scris odată o explicație a RankNTypes că unii oameni par să fi găsit util, așa că am'll se referă la faptul că.

Cu referire Tom Crockett's excelent raspuns, avem:

O monadă este...

  • O endofunctor, T : X -> X
  • Un transformării naturale, μ : T × T -> T, unde × mijloace functor compoziție
  • Un transformării naturale, η : I -> T, unde I este identitatea endofunctor pe X

...satisface aceste legi:

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

Cum putem traduce asta Haskell cod? Ei bine, las's începe cu noțiunea de naturale de transformare:

-- | 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 }

Un tip de forma f :-> geste analog cu o funcție de tip, dar în loc de gândire de ea ca un *funcția* între două *tipuri* (a fel), cred că de ea ca un **morfism** între două **functori** (fiecare de un fel de -> *`). Exemple:

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

Practic, în Haskell, transformari naturale sunt funcții de tip f x pentru un alt tip g x astfel încât " x " tip de variabilă este "inaccesibil" pentru a apelantului. Deci, de exemplu, sortare :: Ord a => [a] -> [o] nu poate fi făcut într-un naturale de transformare, deoarece's "pretentios" despre ce tipuri putem instantia pentru "a". Un mod intuitiv eu folosesc de multe ori să cred că acest lucru este urmatoarea:

  • Un functor este un mod de operare pe conținut a ceva fără a atinge structură.
  • Un naturale de transformare este un mod de operare pe structura de ceva, fără a atinge sau se uită la conținut.

Acum, cu asta, las's a aborda clauze de definiție.

Prima clauză este "un endofunctor, T : X -> X." ei Bine, fiecare Functor în Haskell este un endofunctor în ceea ce oamenii numesc "Hask categorie," ale căror obiecte sunt Haskell tipuri (de genul`) și a căror morfisme sunt Haskell funcții. Acest lucru sună ca un complicat declarație, dar's, de fapt, un foarte banal. Asta înseamnă că un Functor f :: -> oferă mijloacele de a construi o tip `f a :: pentru oriceo :: *și o funcțiefmap f :: f o -> f boricef :: a -> b`, și că acestea se supun functor legi.

A doua clauză: "Identitatea" functor în Haskell (care vine cu Platforma, astfel încât să puteți importa doar ea) este definit astfel:

newtype Identity a = Identity { runIdentity :: a }

instance Functor Identity where
    fmap f (Identity a) = Identity (f a)

Deci transformarea naturală η : I -> T de la Tom Crockett's definiție poate fi scris în acest fel pentru orice Monadă "exemplu" t`:

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

A treia clauză: compoziția de doi functori în Haskell poate fi definit în acest fel (pe care, de asemenea, vine cu Platforma):

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)

Deci transformarea naturală μ : T × T -> T de la Tom Crockett's definiție poate fi scris astfel:

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

Afirmația că acesta este un monoid în categoria de endofunctors atunci înseamnă că Compune (parțial aplicat doar primii doi parametri) este asociativă, și că "Identitate" este element de identitate. I. e., următoarele isomorphisms dețină:

  • Compune f (Compune g h) ~= Compunere (Compunere f g) h
  • Compune Identitate f ~= f
  • Compun Identitatea g ~= g

Acestea sunt foarte ușor pentru a dovedi că Compune și "Identitate" sunt definite ca newtype, și Haskell Rapoarte defini semantica newtype ca un izomorfism între tipul fiind definit și tipul de argument newtype's de date de constructor. Deci, de exemplu, să's a dovedi Compune Identitate f ~= 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.
Comentarii (4)

Notă: nu, Nu e't de adevărat. La un moment dat a existat un comentariu la acest raspuns de la Dan Piponi el însuși spune că cauza și efect de aici a fost exact invers, că el a scris articolul, ca răspuns la James Fumez's quip. Dar se pare că a fost eliminat, probabil, de unele compulsiv mai ordonat.

Mai jos este al meu original răspuns.


L's destul de posibil ca Zână a citit De Monoids să Monadele, un post în care Dan Piponi (sigfpe) provine de monadele din monoids în Haskell, cu multe discuții din categoria teorie și mențiunea explicită a "categoria de endofunctors pe Hask" . În orice caz, nimeni care întreabă ce înseamnă pentru o monadă să fie un monoid în categoria de endofunctors ar putea beneficia de citit această derivare.

Comentarii (1)

Am venit la acest post prin a înțelege mai bine inferență de faimosul citat de Mac Lane's Teoria Categorie Pentru Lucru Matematician. În descrierea ce este ceva, l's de multe ori la fel de utile pentru a descrie ceea ce se's nu. Faptul că Mac Lane folosește descriere pentru a descrie o Monadă, s-ar putea presupune că descrie ceva unic pentru monadele. Poarte cu mine. Pentru a dezvolta o mai bună înțelegere a situației, cred că trebuie să fie făcut clar faptul că el este nu descrie ceva care este unic pentru monadele; declarația la fel descrie Aplicative și Săgeți, printre altele. Pentru același motiv pentru care putem avea două monoids pe Int (Suma și Produsul), putem avea mai multe monoids pe X in categoria de endofunctors. Dar există chiar mai mult pentru a asemănărilor. Ambele Monadă și Aplicative îndeplinesc criteriile:

  • endo => orice săgeată, sau morfism care începe și se termină în același loc
  • functor => orice săgeată, sau morfism între două Categorii

    (de exemplu, în de zi cu zi `un Copac -> Lista b, dar în Categoria de Copac -> Lista)

  • monoid => singur obiect; de exemplu, un singur tip, dar în acest context, numai în ceea ce privește stratul extern; astfel, putem't au Copac -> Lista, doar Lista -> Lista. Declarația utilizează "Categorie de..." Aceasta definește domeniul de aplicare al declarației. Ca un exemplu, Functor Categorie descrie domeniul de aplicare def -> g , respectiv,Orice functor -> Orice functor, de exemplu,Tree -> Lista " sau " Tree -> Arbore . <P>Ce-o declarație Categorică nu specifica descrie unde _anything și totul este permitted_. <P>În acest caz, în interiorul functori, -> akaun -> bnu este specificat ceea ce înseamnă Nimic -> Orice, inclusiv Orice altceva. Ca imaginatia mea sare la Int -> String, acesta include, de asemenea, Integer -> Poate Int "sau chiar" Poate Dublu -> Fie String Int unde o :: Poate Dubla; b :: Fie Șirul Int. Atât declarația vine împreună, după cum urmează:
  • functor domeniul de aplicare :: f o -> g b (de exemplu, orice parametrizate tip la orice parametrizate tip)
  • endo + functor :: f o -> f b (adică, nici unul parametrizate tip la fel parametrizate tip) ... altfel spus,
  • un monoid în categoria de endofunctor Deci, în cazul în care este puterea acestui construct? Pentru a aprecia pe deplin dinamica, am nevoie să văd că tipice desene de un monoid (singur obiect cu ceea ce pare a fi o săgeată de identitate, :: singur obiect -> singur obiect), nu reușește să ilustrez faptul că'm-a permis să folosească o săgeată parametrizate cu any number de monoid valori, de la one tip obiect permisă în Monoid. La endo, ~ săgeată de identitate definiția echivalenței ignores de functor's type value și atât tipul și valoarea cea mai interioară, "sarcina utila" strat. Astfel, echivalența returnează "adevărat" în orice situație în care functorială tipuri se potrivesc (de exemplu, Nimic nu -> Doar -> Nimiceste echivalent cuDoar -> Doar -> Doar deoarece acestea sunt atât de "Poate" - > Poate -> Poate).

    Sidebar: ~ afara este conceptual, dar este cel mai lăsat simbol în `f-o`. Ea descrie, de asemenea, ceea ce "Haskell" citește-în primul rând (big picture); deci, este de Tip "afara" în ceea ce privește un Tip Valoare. Relația între straturi (un lanț de referințe) în programare nu este ușor să se refere în Categorie. Categoria de Set este folosit pentru a descrie Tipuri (Int, Siruri de caractere, Poate Int etc.) care include Categoria de Functor (Tipuri parametrizate). Referință lanț: Functor Tip, Functor valori (elemente de care Functor's a stabilit, de exemplu, Nimic, Doar), și, la rândul său, orice altceva fiecare functor valoare puncte. În Categoria relația este descrisă în mod diferit, de exemplu, `return :: a -> m` este considerat o persoană fizică transformarea dintr-un Functor la un alt Functor, diferit de orice menționate până acum. Înapoi la firul principal, toate în toate, pentru orice definită tensor produs și o valoare neutră, declarația sfârșește prin a descrie un uimitor de puternic calcul construct născut din paradoxal structura:

  • la exterior apare ca un singur obiect (de exemplu, :: Lista); static
  • dar în interior, permite o mulțime de dinamica
  • orice număr de valori de același tip (de exemplu, Gol | ~Nevidă) ca furaj pentru funcțiile de orice aritate. Tensor produs va reduce orice număr de intrări la o singură valoare pentru stratul extern (~ori asta nu spune nimic despre sarcină utilă)
  • gamă infinită de both tipul și valori pentru mai stratul interior În Haskell, a clarifica aplicabilitatea declarație este important. Puterea și versatilitatea acestui construct, nu are absolut nimic de-a face cu o monadă per se. Cu alte cuvinte, construcția nu se bazează pe ceea ce face o monadă unică. Atunci când încearcă să dau seama dacă pentru a construi un cod cu o comună de context, pentru a sprijini calcule care depind unul de celălalt, față de calcule care pot fi rulate în paralel, aceasta infama declarație, cu la fel de mult ca-l descrie, nu este un contrast între alegerea Aplicative, Săgeți și Monade, ci mai degrabă este o descriere a cât de mult sunt la fel. Pentru decizia de la mana, afirmația este discutabilă. Acest lucru este adesea înțeles greșit. Declarația a merge pe pentru a descrie se alăture :: m (m, o) -> m-o ca tensor produs pentru monoidal endofunctor. Cu toate acestea, nu articula cum, în contextul acestei declarații, (<*>) ar putea, de asemenea, au fost de asemenea alese. Acesta este cu adevărat un exemplu de șase/jumătate de duzină. Logica pentru care combină valorile sunt exact la fel; același intrare generează aceeași ieșire din fiecare (spre deosebire de Suma și Produsul monoids pentru Int, deoarece acestea generează rezultate diferite atunci când combinarea Int). Deci, să recapitulăm: Un monoid în categoria de endofunctors descrie:
   ~t :: m * -> m * -> m *
   and a neutral value for m *

(<*>) " și "(>>=) ambele oferă acces simultan la cei doi " m " valori în scopul de a calcula singur valoarea de returnare. Logica folosit pentru a calcula valoarea returnată este exact la fel. Dacă nu au fost pentru diferite forme de funcțiile pe care le parametrizarea (f :: a -> b "versus" k :: o -> m b) și poziția parametru cu același tip de întoarcere de calcul (de exemplu, a -> b -> b "versus" b -> a -> b pentru fiecare, respectiv), nu cred că ar putea fi parametrizate în monoidal logica, tensor produs, pentru reutilizare în ambele definiții. Ca un exercițiu pentru a se face înțeles, încercați să-și pună în aplicare ~t, și va termina cu (<*>) " și " (>>=) în funcție de modul în care decideți să-l definească pentrutoate un b. Dacă ultimul punct este la minim din punct de vedere conceptual adevărat, atunci explică precis, și numai în calcul diferența dintre Aplicativ și Monadă: funcțiile pe care le poate măsura. Cu alte cuvinte, diferența este external pentru punerea în aplicare a acestor clase de tip. În concluzie, în propria mea experiență, Mac Lane's faimosul citat oferit un mare "du-te" meme, un guidepost pentru mine de referință în timp ce navigați prin felul meu de Categorie pentru a înțelege mai bine expresii utilizate în Haskell. Reușește la capturarea domeniul de aplicare de o puternică capacitate de calcul a făcut minunat accesibile în Haskell. Cu toate acestea, există o ironie în modul în care am înțeles greșit declarația's aplicabilitatea în afara de monadă, și ceea ce sper transmis aici. Tot ceea ce descrie a dovedit a fi ceea ce este similar între Aplicative și Monade (și Săgeți printre altele). Ceea ce nu't spune este tocmai mic, dar util distincție între ele. - E

Comentarii (0)

Răspunsurile aici fac o treabă excelentă în definirea atât monoids și monade, cu toate acestea, ei încă nu't par să răspundă la întrebarea:

Și pe mai puțin important să rețineți, acest lucru este adevărat și dacă așa ar putea oferi o explicație (sperăm, una care poate fi înțeles de către cineva care nu't au mult Haskell experiență)? Esența problemei care lipsește aici, este diferit notiunea de "monoid", așa-numita categorification mai precis ... cel de monoid într-o categorie monoidal. Din păcate Mac Lane's carte de sine face foarte confuz: Toate-a spus, o monadă în " X "este doar un monoid în categoria de endofunctors de "X", cu produs × înlocuită cu compoziția de endofunctors și unitatea set de identitate endofunctor.

Principala confuzie

De ce este această confuzie? Pentru că nu definește ceea ce este "monoid în categoria de endofunctors" de "X". În schimb, această frază sugerează lua un monoid în interiorul setul de toate endofunctors împreună cu functor compoziție ca operație binară și identitatea functor ca un monoidal unitate. Care funcționează foarte bine și se transformă într-un monoid orice subset de endofunctors care conține identitatea functor și este închis sub functor compoziție. Totuși, acest lucru nu este o interpretare corectă, pe care cartea nu reușește să facă clar în această etapă. O Monadă " f " este o fix endofunctor, nu un subset de endofunctors închis în compoziție. O construcție comună este de a folosi " f "a genera un monoid de a lua un set de toate" k "ori compoziții f^k = f(f(...)) de" f " cu sine, inclusiv k=0care corespunde identitateaf^0 = id. Și acum setat " S " de toate aceste puteri pentru toatek>=0` este într-adevăr un monoid "cu produs × înlocuit cu o compoziție de endofunctors și unitatea set de identitate endofunctor". Și încă:

  • Acest monoid " S "poate fi definit pentru orice functor" f "sau chiar la propriu pentru orice auto-harta de "X". Este monoid generate de "f".
  • La monoidal structura " S "dat de functor compoziția și identitatea functor nu are nimic de-a face cu" f " a fi sau a nu fi o monadă. Și pentru a face lucrurile și mai confuze, definiția de "monoid în monoidal categoria" vine mai târziu în carte, după cum puteți vedea de la cuprins. Și totuși înțelege această noțiune este absolut esențială pentru înțelegerea legătură cu monadele.

    (Strict) monoidal categorii

    O să-Capitolul VII pe Monoids (care vine mai târziu decât Capitolul VI pe Monadele), găsim definiția de așa-numitele stricte categorie monoidal ca triple (B, *, e), unde " B "este o categorie,: B x B-> B` o bifunctor* (functor cu privire la fiecare componentă cu alte componente fixe) și" e "este o unitate de obiect în "B", satisfacerea asociativitatea și unitatea de legi:

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

pentru orice obiecte a,b,caB, și același identități pentru orice morfismea,b,c " cu " e "este înlocuită cu" id_e, identitatea morfism de "e". Acum este instructiv să observăm că în cazul nostru de interes, unde " B "este categoria de endofunctors de" X "cu transformari naturale ca morfisme,` al functor compoziția și" e " identitatea functor, toate aceste legi sunt îndeplinite, ca pot fi verificate direct. Ce vine după în carte este definiția de "egal" categorie monoidal, unde legile deține doar modulo fix unele transformari naturale îndeplinesc așa-numitele coerența relațiilor*, care însă nu este important pentru cazuri de endofunctor categorii.

Monoids în monoidal categorii

În cele din urmă, în secțiunea 3 "Monoids" din Capitolul VII, reale definiție este dat de:

Un monoid " c "într-o categorie monoidal (B, *, e) este un obiect de "B", cu două săgeți (morfisme)

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

3 diagrame comutative. Reamintim că, în cazul nostru, acestea sunt morfisme in categoria de endofunctors, care sunt naturale transformări corespunde exact "participă" și "întors" pentru o monadă. Conexiunea devine și mai clară atunci când facem compoziție * mai explicit, înlocuind `c * c " cu "c^2, unde" c " este noastre monadă. În cele din urmă, observăm că 3 comutativ diagrame (în definiția de un monoid în monoidal categorie) sunt scrise pentru general (non-stricte) monoidal categorii, în timp ce în cazul nostru toate naturale transformări care apar ca parte a monoidal categorie sunt de fapt identitatea. Care va face diagrame exact la fel ca cei din definiția de o monadă, făcând corespondența completă.

Concluzie

În rezumat, orice monadă este, prin definiție, un endofunctor, prin urmare, un obiect din categoria de endofunctors, unde monadic "participă" și "întors" operatorii satisface definiția de un monoid în special (strict) categorie monoidal. Invers, orice monoid în categorie monoidal a endofunctors este, prin definiție, un triplu (c, mu, nu) constând dintr-un obiect și două săgeți, de exemplu naturale transformări în cazul nostru, satisfăcând aceleași legi ca o monadă. În cele din urmă, rețineți diferența esențială între (clasică) monoids și mai general monoids în monoidal categorii. Cele două săgeți mu și nu de mai sus nu mai este o operație binară și o unitate într-un set. În schimb, ai un fix endofunctor "c". La functor compoziție * și identitatea functor singur nu oferă o structură necesare pentru monadă, în ciuda faptului că confuze remarcă în carte. O altă abordare ar fi să comparăm cu standardul monoid " C "de toate auto-hărți de un set de "A", unde operație binară este structura, care poate fi văzut la harta standard de produs cartezian C x Cîn "C". Trecerea la categorified monoid, suntem înlocuirea produsului cartezian " x "cu functor compoziție"*", iar la operație binară este înlocuit cu transformarea naturalămudin c * cac`, care este o colecție de "adere" operatorii

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

pentru fiecare obiect " T " (tastați în programare). Și elemente de identitate clasică monoids, care pot fi identificate cu imagini de hărțile de pe un fix într-un punct-set, înlocuit cu o colecție de "returnare" operatorii

return: T->c(T) 

Dar acum nu mai sunt produse carteziene, deci nu perechi de elemente și astfel nu operații binare.

Comentarii (0)