Un foo gratuit se trouve être la chose la plus simple qui satisfait toutes les lois du foo. C'est-à-dire qu'il satisfait exactement aux lois nécessaires pour être un fou et rien de plus.
Un foncteur oublieux est celui qui «oublie» une partie de la structure en passant d'une catégorie à l'autre.
Des foncteurs donnés F : D -> C, et G : C -> D, disons-nous F -| G, Fsont adjoints à gauche Gou Gsont adjoints à droite Fchaque fois que tout a, b: F a -> best isomorphe à a -> G b, où les flèches proviennent des catégories appropriées.
Formellement, un foncteur libre est laissé adjoint à un foncteur oublieux.
Le monoïde gratuit
Commençons par un exemple plus simple, le monoïde libre.
Prenez un monoïde, qui est défini par un ensemble de support T, une fonction binaire pour écraser une paire d'éléments ensemble f :: T → T → T, et unit :: T, de sorte que vous avez une loi associative, et une loi d'identité: f(unit,x) = x = f(x,unit).
Vous pouvez créer un foncteur à Upartir de la catégorie des monoïdes (où les flèches sont des homomorphismes monoïdes, c'est-à-dire qu'ils s'assurent qu'ils correspondent unità unitl'autre monoïde et que vous pouvez composer avant ou après le mappage à l'autre monoïde sans changer de signification) à la catégorie d'ensembles (où les flèches ne sont que des flèches de fonction) qui «oublie» l'opération et unit, et vous donne simplement l'ensemble de support.
Ensuite, vous pouvez définir un foncteur Fde la catégorie des ensembles à la catégorie des monoïdes qui reste adjointe à ce foncteur. Ce foncteur est le foncteur qui associe un ensemble aau monoïde [a], où unit = []et mappend = (++).
Donc, pour passer en revue notre exemple jusqu'à présent, en pseudo-Haskell:
U : Mon → Set -- is our forgetful functor
U (a,mappend,mempty) = a
F : Set → Mon -- is our free functor
F a = ([a],(++),[])
Ensuite, pour montrer que Fc'est gratuit, nous devons démontrer qu'il est laissé adjoint à U, un foncteur oublieux, c'est-à-dire, comme nous l'avons mentionné ci-dessus, nous devons montrer que
F a → b est isomorphe à a → U b
maintenant, rappelez-vous que la cible de Fest dans la catégorie Mondes monoïdes, où les flèches sont des homomorphismes monoïdes, nous avons donc besoin d'un pour montrer qu'un homomorphisme monoïde de [a] → bpeut être décrit précisément par une fonction de a → b.
Dans Haskell, nous appelons le côté de cela qui vit dans Set(euh, Haskla catégorie de types Haskell que nous prétendons être Set), juste foldMap, qui, lorsqu'elle est spécialisée de Data.Foldableà Lists, a du type Monoid m => (a → m) → [a] → m.
Il y a des conséquences qui découlent de cette adjonction. Notamment, si vous oubliez, puis construisez avec free, puis oubliez à nouveau, c'est comme vous l'avez oublié une fois, et nous pouvons l'utiliser pour construire la jointure monadique. depuis UFUF~ U(FUF)~ UF, et nous pouvons passer dans l'homomorphisme monoïde d'identité de [a]à [a]travers l'isomorphisme qui définit notre adjonction, obtenir qu'un isomorphisme de liste [a] → [a]est une fonction de type a -> [a], et c'est juste un retour pour les listes.
Vous pouvez composer tout cela plus directement en décrivant une liste en ces termes avec:
newtype List a = List (forall b. Monoid b => (a -> b) -> b)
La monade libre
Qu'est-ce qu'une Free Monad ?
Eh bien, nous faisons la même chose que nous faisions avant, nous commençons avec un foncteur oublieux U de la catégorie des monades où les flèches sont des homomorphismes de monade à une catégorie d'endofoncteurs où les flèches sont des transformations naturelles, et nous recherchons un foncteur qui est laissé adjoint pour que.
Alors, comment cela se rapporte-t-il à la notion de monade libre telle qu'elle est généralement utilisée?
Savoir que quelque chose est une monade libre, Free fvous dit que donner un homomorphisme de monade à partir de Free f -> m, c'est la même chose (isomorphe à) que donner une transformation naturelle (un homomorphisme de foncteur) à partir de f -> m. Rappelez-vous que F a -> bdoit être isomorphe pour a -> U bque F soit laissé adjoint à U. U ici mappé des monades aux foncteurs.
F est au moins isomorphe au Freetype que j'utilise dans mon freepackage sur le piratage.
Nous pourrions également le construire dans une analogie plus étroite avec le code ci-dessus pour la liste gratuite, en définissant
class Algebra f x where
phi :: f x -> x
newtype Free f a = Free (forall x. Algebra f x => (a -> x) -> x)
Cofree Comonads
Nous pouvons construire quelque chose de similaire, en regardant l'adjoint de droite d'un foncteur oublieux en supposant qu'il existe. Un foncteur cofree est simplement / à droite adjoint / à un foncteur oublieux, et par symétrie, savoir que quelque chose est un comonad cofree revient à savoir que donner un homomorphisme comonad à partir de w -> Cofree fest la même chose que donner une transformation naturelle à partir de w -> f.