Un foo libre resulta ser lo más simple que satisface todas las leyes de 'foo'. Es decir, satisface exactamente las leyes necesarias para ser un tonto y nada más.
Un functor olvidadizo es aquel que "olvida" parte de la estructura a medida que pasa de una categoría a otra.
Dados functores F : D -> C
, y G : C -> D
, decimos F -| G
, F
se deja adjunto a G
, o G
es justo contiguo a F
cada vez que a, b: F a -> b
es isomorfo a a -> G b
, donde las flechas provienen de las categorías apropiadas.
Formalmente, un functor gratuito se deja adjunto a un functor olvidadizo.
El monoide libre
Comencemos con un ejemplo más simple, el monoide gratuito.
Tome un monoide, que se define por un conjunto de soporte T
, una función binaria para triturar un par de elementos juntos f :: T → T → T
, y una unit :: T
, de manera que usted tiene una ley asociativa, y una ley de identidad: f(unit,x) = x = f(x,unit)
.
Puede hacer un funtor U
de la categoría de monoides (donde las flechas son homomorfismos monoides, es decir, que aseguran se asignan unit
a unit
por otro monoide, y que se pueden componer antes o después de la cartografía a la otra monoid sin cambiar el significado) a la categoría de conjuntos (donde las flechas son solo flechas de función) que 'se olvida' de la operación unit
y solo le da el conjunto de portadores.
Luego, puede definir un functor F
desde la categoría de conjuntos hasta la categoría de monoides que se adjunta a este functor. Ese functor es el functor que asigna un conjunto a
al monoide [a]
, donde unit = []
y mappend = (++)
.
Entonces, para revisar nuestro ejemplo hasta ahora, 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],(++),[])
Luego, para mostrar F
es gratuito, tenemos que demostrar que se deja adjunto a U
un functor olvidadizo, es decir, como mencionamos anteriormente, tenemos que demostrar que
F a → b
es isomorfo a a → U b
Ahora, recuerde que el objetivo de F
está en la categoría Mon
de monoides, donde las flechas son homomorfismos monoides, por lo que necesitamos un para demostrar que un homomorfismo monoide [a] → b
puede describirse precisamente por una función de a → b
.
En Haskell, llamamos al lado de esto que vive en Set
(er, Hask
la categoría de tipos de Haskell que pretendemos es Set), simplemente foldMap
, que cuando se especializa desde Data.Foldable
a Listas tiene tipo Monoid m => (a → m) → [a] → m
.
Hay consecuencias que se derivan de que esto sea un complemento. Notablemente, si olvidas, entonces construye con gratis, luego vuelve a olvidar, es como lo olvidaste una vez, y podemos usar esto para construir la unión monádica. desde UFUF
~ U(FUF)
~ UF
, y podemos pasar el homomorfismo monoide de identidad de [a]
a [a]
través del isomorfismo que define nuestro adjunto, hacer que una lista de isomorfismo [a] → [a]
sea una función de tipo a -> [a]
, y esto es solo el retorno para las listas.
Puede componer todo esto más directamente describiendo una lista en estos términos con:
newtype List a = List (forall b. Monoid b => (a -> b) -> b)
La mónada libre
Entonces, ¿qué es una mónada libre ?
Bueno, hacemos lo mismo que hicimos antes, comenzamos con un functor olvidadizo U de la categoría de mónadas donde las flechas son homomorfismos de mónada a una categoría de endofunctores donde las flechas son transformaciones naturales, y buscamos un functor que quede adjunto a ese.
Entonces, ¿cómo se relaciona esto con la noción de una mónada libre como se usa generalmente?
Sabiendo que algo es una mónada libre, Free f
te dice que dar un homomorfismo de mónada Free f -> m
es lo mismo (isomorfo a) que dar una transformación natural (un homomorfismo functor) f -> m
. Recuerde que F a -> b
debe ser isomorfo a -> U b
para que F se quede junto a U. U aquí asigna mónadas a functors.
F es al menos isomorfo al Free
tipo que uso en mi free
paquete de piratería.
También podríamos construirlo en una analogía más estricta con el código anterior para la lista gratuita, definiendo
class Algebra f x where
phi :: f x -> x
newtype Free f a = Free (forall x. Algebra f x => (a -> x) -> x)
Cofree Comonads
Podemos construir algo similar, mirando el adjunto correcto a un functor olvidadizo, suponiendo que exista. Un cofundador es simplemente / justo adjunto / a un olvidadizo, y por simetría, saber que algo es un cofre comonad es lo mismo que saber que dar un comonad homomorfismo w -> Cofree f
es lo mismo que dar una transformación natural w -> f
.