2013-09-21 9 views
6

Sto cercando di riconciliare la definizione categoriale di Monad con le altre rappresentazioni/definizioni generali che ho visto in altri tutorial/libri.Monade da tutti gli angoli - Matematica, diagrammatica e programmatica

Qui di seguito, io sono (forse con forza) cercando di portare le due definizioni stretti, si prega di segnalare gli errori e fornire correzioni, dove mai necessario

Quindi, a partire dalla definizione delle monadi

Monadi sono solo monoidi nella categoria dei endofuntor.

e con un po 'di comprensione di endofunctors, presumo una Monade può essere scritta come

((a->b)->Ma->Mb)->((b->c)->Mb->Mc) 

Il 'Type' di LHS (lato sinistro) è Mb, e il tipo di RHS è Mc, quindi suppongo che posso scrivere come qui sotto

Mb-> (b->c)-> Mc, **which is how we define bind** 

Ed ecco come vedo Monadi nella categoria di endofuctors (che a loro volta sono in Category C, con 'types' come objects)

Monad Visually.

Tutto ciò ha senso?

risposta

9

Beh, um, penso che tu sia un po 'fuori. Una monade è un endofunctore, che in Hask (La categoria dei tipi Haskell) è qualcosa del tipo F :: * -> * con qualche funzione che sa iniettare morfismi (funzioni) nella sottocategoria di Hask con funzioni su F s come morfismi e F s come oggetti, fmap. Quello che hai lì sembra essere una trasformazione naturale in Hask.

Esempi: Maybe, Either a, (,) a, ecc ..

Ora anche una monade deve avere 2 trasformazioni naturali (Functor F, Functor g => F a -> G a in Hask).

n : Identity -> M 
u : M^2 -> M 

o nel codice haskell

n :: Identity a -> M a -- Identity a == a 
u :: M (M a) -> M a 

che corrispondono rispettivamente a return e join.

Ora dobbiamo arrivare a >>=. Quello che avevi come vincolo era in realtà solo fmap, quello che effettivamente vogliamo è m a -> (a -> m b) -> m b. Questo è facilmente definito come

m >>= f = join $ f `fmap` m 

Tada! Abbiamo monadi. Ora per questo monoide di endofunzionisti.

Un endofuntorico monoide avrebbe un funtore come oggetti e trasformazioni naturali come morfismi. La cosa interessante è che il prodotto di due endofuncori è la loro composizione.Ecco il codice Haskell per il nostro nuovo monoid

type (f <+> g) a = f (g a) 
class Functor m => Monoid' m where 
    midentity' :: Identity a -> m a 
    mappend' :: (m <+> m) a -> m a 

Questo desugars a

midentity' :: a -> m a 
mappend' :: m (m a) -> m a 

sembra familiare?

+0

aah, Monad è endofuctor, come mi sono perso. Adesso è chiaro, grazie. –

5

La definizione "Monade sono solo monoidi nella categoria dei endofunzionisti", che sebbene sia vero è un brutto punto di partenza. Proviene da uno blog post che era in gran parte inteso per essere uno scherzo. Ma se sei interessato alla corrispondenza può essere dimostrato in Haskell:

La descrizione del laico di una categoria è una raccolta astratta di oggetti e morfismi tra gli oggetti. I mapping tra categorie sono chiamati functors e mappano oggetti e morfismi ai morfismi in modo associativo e preservano le identità. Un endofunctor è un funtore di una categoria a se stesso.

{-# LANGUAGE MultiParamTypeClasses, 
      ConstraintKinds, 
      FlexibleInstances, 
      FlexibleContexts #-} 

class Category c where 
    id :: c x x 
    (.) :: c y z -> c x y -> c x z 

class (Category c, Category d) => Functor c d t where 
    fmap :: c a b -> d (t a) (t b) 

type Endofunctor c f = Functor c c f 

mappature tra funtori che soddisfano il cosiddetto naturality conditions sono chiamati trasformazioni naturali. In Haskell queste sono funzioni polimorfiche di tipo: (Functor f, Functor g) => forall a. f a -> g a.

Un monade su una categoria C è tre cose (T,η,μ), T è endofunctor e 1 è il funtore identità su C. Mu e eta sono due trasformazioni fisiche che soddisfano un triangle identity e un associatività identità, e sono definiti come:

  • η : 1 → T
  • μ : T^2 → T

In Haskell μ è join e η è return

  • return :: Monad m => a -> m a
  • join :: Monad m => m (m a) -> m a

Una definizione categoriale della Monade in Haskell potrebbe scrivere:

class (Endofunctor c t) => Monad c t where 
    eta :: c a (t a) 
    mu :: c (t (t a)) (t a) 

L'operatore si legano può essere derivata da questi.

(>>=) :: (Monad c t) => c a (t b) -> c (t a) (t b) 
(>>=) f = mu . fmap f 

Si tratta di una definizione completa, ma in modo equivalente si può anche dimostrare che le leggi Monade possono essere espresse come leggi monoid con una categoria funtore. Possiamo costruire questa categoria di functor che è una categoria con oggetti come funtori (cioè mappature tra categorie) e trasformazioni naturali (cioè mappature tra funtori) come morfismi. In una categoria di endofosfori tutti i funtori sono funtori tra la stessa categoria.

newtype CatFunctor c t a b = CatFunctor (c (t a) (t b)) 

possiamo mostrare questo dà luogo ad una categoria con composizione funtore la composizione morfismo:

-- Note needs UndecidableInstances to typecheck 
instance (Endofunctor c t) => Category (CatFunctor c t) where 
    id = CatFunctor id 
    (CatFunctor g) . (CatFunctor f) = CatFunctor (g . f) 

Il monoide ha la solita definizione:

class Monoid m where 
    unit :: m 
    mult :: m -> m -> m 

un monoide su una categoria di i funtori hanno una trasformazione naturale come identità a e un'operazione di moltiplicazione che combina le trasformazioni naturali. La composizione di Kleisli può essere definita per soddisfare la legge sulla moltiplicazione.

(<=<) :: (Monad c t) => c y (t z) -> c x (t y) -> c x (t z) 
f <=< g = mu . fmap f . g 

E così avete "Monadi sono monoidi solo nella categoria endofunctors", che è solo una versione "pointfree" della normale definizione di monadi da endofunctors e (mu, ETA).

instance (Monad c t) => Monoid (c a (t a)) where 
    unit = eta 
    mult = (<=<) 

Con un po 'di sostituzione si può dimostrare che le proprietà di monoidali (<=<) sono dichiarazione equivalente del triangolo e associatività diagrammi per le trasformazioni naturali della monade.

f <=< unit == f 
unit <=< f == f 

f <=< (g <=< h) == (f <=< g) <=< h 

Se siete interessati a diagrammatic representations ho scritto un po 'su di loro che rappresentano con i diagrammi di stringa.

2

Mi sembra che si omesso cose importanti:

  • c'è la parola “monoide” nella definizione. Non l'hai considerato nel tuo post.
  • È meglio sostituirlo con "oggetto monoide" per essere precisi. I monoidi vivono nell'algebra astratta, gli oggetti monoidi vivono nella teoria delle categorie. Specie diverse
    • I monoidi sono oggetti monoidi in alcune categorie, ma qui non è rilevante.
  • Un oggetto monoide può essere definito solo in una categoria monoidale.

Quindi, un percorso per comprendere la definizione è il seguente.

  • si considera una categoria di endofunctors (consente di chiamare E) sulla categoria di tipi e funzioni Hask Haskell. I suoi oggetti sono funtori su Hask, un morfismo in esso da F a G è una funzione polimorfica di tipo F a -> G a con qualche proprietà.
  • Si considera una struttura su E che la trasforma in una categoria monoidale, cioè composizione di funtori e funtori di identità.
  • Considerate la definizione di un oggetto monoide, ad es. da Wikipedia.
  • Considerate cosa significa nella vostra specifica categoria E. Significa che M è un endofunctor e μ ha lo stesso tipo di "join" e η ha lo stesso tipo di "return".
  • "(>> =)" è definito tramite "join".

Un consiglio. Non cercare di esprimere tutto in Haskell. È progettato per scrivere programmi, non matematica. La notazione matematica è più comoda in questo caso perché è possibile scrivere la composizione dei funtori come "∘" senza problemi con il controllo del tipo.

Problemi correlati