Un foo libero sembra essere la cosa più semplice che soddisfa tutte le leggi "foo". Vale a dire che soddisfa esattamente le leggi necessarie per essere un pazzo e niente di più.
Un funzione smemorato è uno che "dimentica" parte della struttura mentre passa da una categoria all'altra.
Dati funzioni F : D -> C
, e G : C -> D
, diciamo F -| G
, F
è lasciato aggiunto G
, o G
è aggiunto a destra F
ogni volta che tutto a, b: F a -> b
è isomorfo a -> G b
, dove le frecce provengono dalle categorie appropriate.
Formalmente, un funzione libera viene aggiunta a un funzione smemorato.
Il monoide libero
Cominciamo con un esempio più semplice, il monoide libero.
Prendete un monoide, che è definita da alcuni set vettore T
, una funzione binaria per schiacciare una coppia di elementi insieme f :: T → T → T
, ed una unit :: T
, in modo tale che si dispone di una legge associativa, e una legge di identità: f(unit,x) = x = f(x,unit)
.
Si può fare un funtore U
dalla categoria di monoidi (dove le frecce sono homomorphisms monoid, che è, assicurano mappano unit
al unit
dall'altra monoid, e che è possibile comporre prima o dopo la mappatura all'altra monoide senza cambiare significato) alla categoria di insiemi (in cui le frecce sono solo frecce di funzione) che "dimenticano" l'operazione e unit
ti danno il set di corriere.
Quindi, è possibile definire un funzione F
dalla categoria di set alla categoria di monoidi che viene aggiunta in aggiunta a questo funzione. Quel functor è il functor che mappa un set a
sul monoide [a]
, dove unit = []
e mappend = (++)
.
Quindi, per rivedere il nostro esempio finora, in pseudo-Haskell:
U : Mon → Set -- is our forgetful functor
U (a,mappend,mempty) = a
F : Set → Mon -- is our free functor
F a = ([a],(++),[])
Quindi per mostrare F
è gratuito, dobbiamo dimostrare che è lasciato adiacente U
, un funzione smemorato, cioè, come abbiamo menzionato sopra, dobbiamo mostrare che
F a → b
è isomorfo a a → U b
ora, ricorda che l'obiettivo di F
è nella categoria Mon
dei monoidi, in cui le frecce sono omomorfismi monoidi, quindi abbiamo bisogno di dimostrare che un omomorfismo monoide [a] → b
può essere descritto precisamente da una funzione di a → b
.
In Haskell, noi chiamiamo il lato di questo che vive Set
(ehm, Hask
la categoria dei tipi di Haskell che pretendiamo sia Set), giusto foldMap
, che quando è specializzato dagli Data.Foldable
Elenchi ha il tipo Monoid m => (a → m) → [a] → m
.
Ci sono conseguenze che ne derivano dal fatto che si tratta di un'aggiunta. In particolare, se dimentichi, costruisci con libero, poi dimentica di nuovo, è proprio come hai dimenticato una volta, e possiamo usarlo per costruire l'unione monadica. da UFUF
~ U(FUF)
~ UF
, e possiamo trasmettere l'omomorfismo monoide dell'identità da [a]
a [a]
attraverso l'isomorfismo che definisce la nostra aggiunta, ottenere che un elenco di isomorfismi [a] → [a]
è una funzione di tipo a -> [a]
, e questo è solo un ritorno per gli elenchi.
Puoi comporre tutto questo più direttamente descrivendo un elenco in questi termini con:
newtype List a = List (forall b. Monoid b => (a -> b) -> b)
La monade libera
Quindi cos'è una Monade libera ?
Bene, facciamo la stessa cosa che abbiamo fatto prima, iniziamo con un funzione di dimenticanza U dalla categoria di monadi in cui le frecce sono omomorfismi di monade a una categoria di endofunctor in cui le frecce sono trasformazioni naturali, e cerchiamo un funzione che viene lasciato in aggiunta a tale.
Quindi, in che modo questo si collega alla nozione di monade libera come viene normalmente usata?
Sapere che qualcosa è una monade libera, Free f
ti dice che dare una monade dall'omomorfismo Free f -> m
, è la stessa cosa (da isomorfa a) che dare una trasformazione naturale (un omomorfismo di funzione) da f -> m
. Ricorda che F a -> b
deve essere isomorfo a -> U b
perché F sia lasciato in aggiunta a U. U qui monade mappato su funzione.
F è almeno isomorfo rispetto al Free
tipo che uso nel mio free
pacchetto sull'hackage.
Potremmo anche costruirlo in stretta analogia con il codice sopra per l'elenco libero, definendo
class Algebra f x where
phi :: f x -> x
newtype Free f a = Free (forall x. Algebra f x => (a -> x) -> x)
Cofree Comonads
Possiamo costruire qualcosa di simile, osservando l'aggiunta giusta a un funzione smemorato supponendo che esista. Un funzionario cofree è semplicemente / giusto aggiunta / ad un funzione smemorato e, per simmetria, sapere che qualcosa è un comonad di caffè è lo stesso che sapere che dare un omomorfismo comune w -> Cofree f
è la stessa cosa che dare una trasformazione naturale da w -> f
.