Recientemente he estado desempolvando mi conocimiento sobre cómo funcionan las mónadas. También me presentaron el concepto de 'Comonad' , que se describe como el dual inverso de una mónada . Sin embargo, soy imposible entenderlo.
Para entender a las mónadas, hice la propia analogía para mí:
Las mónadas se pueden ver como "un modelo para construir cintas transportadoras de expresiones".
Para definir una nueva Mónada (un nuevo tipo de sistema de cinta transportadora) debe definir:
- Una forma de poner algo en una cinta transportadora, por ejemplo, 'iniciar' una cinta transportadora. (Conocido como
unit
oreturn
)- Una forma de conectar una máquina (una expresión) que formará parte de una cinta transportadora a una cinta transportadora. (Conocido como
join
obind
o>>=
).(Hay una tercera operación que toma la cinta transportadora actual, tira su contenido y comienza una nueva cinta transportadora conocida como
>>
, pero se usa muy raramente).Para que las máquinas y los transportadores funcionen correctamente juntos, deberá asegurarse de que:
- Si coloca algo en una cinta transportadora y lo pasa a través de una máquina, el resultado debe ser el mismo que cuando lo pasa a través de la máquina manualmente. (Identidad izquierda)
- Si desea colocar una cinta transportadora entre una cinta transportadora ya existente, no debe terminar con una cinta transportadora que tenga una cinta transportadora en la parte superior, sino una cinta transportadora única y más larga. (Identidad correcta)
- No debería importar la salida si usa manualmente la máquina A, y luego pasa el resultado a través del BC conectado al transportador, o si usa AB conectado al transportador y luego pasa el resultado manualmente a través de C. En otras palabras: ((a >> = b) >> = c) debe ser lo mismo que (a >> = (b >> = c)) (Asociatividad)
La cinta transportadora más simple sería la que solo toma la entrada y siempre continúa con la siguiente expresión. Esto es lo que es una 'tubería'.
Otra posibilidad es dejarlo pasar por la siguiente máquina si se cumple alguna condición para el valor. Esto significa que si en algunas de las expresiones intermedias, el valor cambia a algo que ya no está permitido, se omitirá el resto de las expresiones. Esto es lo que hace la mónada 'Quizás' en Haskell.
También puede hacer otras reglas elegantes de copia / cambio condicional en los valores antes o después de pasarlos a una máquina. Un ejemplo: Analizadores (aquí, si una expresión devuelve un resultado de 'falla', el valor anterior a la expresión se usa como salida).
Por supuesto, la analogía no es perfecta, pero espero que brinde una buena representación de cómo funcionan las mónadas.
Sin embargo, estoy teniendo muchos problemas para cambiar esta analogía para entender a Comonads. Sé por las pequeñas cantidades de información que he encontrado en Internet que define un Comonad:
extract
, Que es una especie de reverso dereturn
, es decir, que toma un valor fuera de un Comonad.duplicate
, que es una especie de inverso dejoin
, es decir, crea dos Comonads a partir de una sola.
Pero, ¿cómo se puede instanciar un Comonad si solo podemos extraerlo o duplicarlo? ¿Y cómo se pueden usar realmente? He visto este proyecto increíble y la charla al respecto (que lamentablemente entendí muy poco), pero no estoy seguro de qué parte de la funcionalidad proporciona exactamente un Comonad.
¿Qué es un Comonad? ¿Para qué son útiles? ¿Cómo se pueden usar? ¿Son comestibles?
IO
mónada es el sistema de tiempo de ejecución Haskell, que invocamain
. También hayunsafePerformIO
, por supuesto. Si desea pensar que laMaybe
mónada tiene una "máquina al final de la cinta transportadora", puede usarlamaybe
.cobind
aplicaciones, debe haber alguna función que haga algo útil con la representación interna de su comonad.Respuestas:
Una comonad es, al igual que una mónada, una estructura matemática en la teoría de categorías. El co-prefijo es muy común allí para denotar "inversas" como lo expresas (aunque no creo que los matemáticos puros estén de acuerdo con la elección de la palabra).
En la teoría de categorías hay
categories
, que se ponen brevemente una colección deobjects
(de cualquier tipo o naturaleza, la estructura interna es irrelevante) y algunasarrows
entre estos objetos. Para que algo sea una categoría, las flechas deben seguir algunas leyes (identidad izquierda / derecha y asociatividad), pero eso no es realmente importante aquí.Ahora, la teoría de categorías es muy abstracta / difícil de entender y vasta. Toma mucho tiempo revisarlo todo (y no lo he estudiado formalmente, solo sé algunos conceptos básicos), pero hay una noción que se llama a
dual
. Básicamente, para cada categoría, puede construir unopposite category
simplemente haciendo lo mismo pero "invirtiendo todas las flechas". Esta es una definición muy ingenua, pero es difícil de resumir. El doble de algo en una categoría C es básicamente lo mismo en la categoría opuesta C_op (¿te duele la cabeza todavía?)De todos modos, si tiene una mónada sobre alguna categoría (y una categoría puede ser, por ejemplo, una categoría donde los objetos son tipos en algún lenguaje de programación y las flechas son funciones entre los tipos), entonces una comonad es básicamente lo mismo, solo usted he invertido todas las flechas (algo así como invertir las firmas de funciones en este caso).
Se puede encontrar una descripción más "práctica" (aunque no SUPER práctica) en esta discusión entre Erik Meijer y Brian Beckman, donde están discutiendo la noción de dualidad y cómo Erik "invirtió las flechas"
IEnumerable<T>
en C # cuando creando el marco reactivo yIObservable<T>
(que, por lo que puedo decir, y estoy feliz de que me corrijan, básicamente es una instancia de lista común).Otro ejemplo práctico de comonads mencionado en el video es el
Task<T>
tipo en .NET, dondeTask<U> ContinueWith<U>(Func<Task<T>, U>)
sería el dual debind
(oSelectMany
como se llama en C #)fuente
Desde mi pequeño entendimiento, un comonad es una máquina Rube Goldberg para hacer post-docs:
http://www.willamette.edu/~fruehr/haskell/evolution.html
... lo siento, no pude resistirlo.
fuente