¿Qué es un Comonad y cómo son útiles?

16

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:

  1. Una forma de poner algo en una cinta transportadora, por ejemplo, 'iniciar' una cinta transportadora. (Conocido como unito return)
  2. Una forma de conectar una máquina (una expresión) que formará parte de una cinta transportadora a una cinta transportadora. (Conocido como joino bindo >>=).

(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:

  1. 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)
  2. 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)
  3. 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 de return, es decir, que toma un valor fuera de un Comonad.
  • duplicate, que es una especie de inverso de join, 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?

Qqwy
fuente
2
"¿Cómo se puede instanciar un Comonad si solo podemos extraerlo o duplicarlo?" - Responderé a su pregunta con una pregunta: ¿cómo se puede consumir una mónada si solo puede levantar valores en ellos y secuenciar cálculos?
Benjamin Hodgson
1
La "máquina al final de la cinta transportadora" (aparte: no encuentro analogías tan útiles cuando se habla de mónadas) de la IOmónada es el sistema de tiempo de ejecución Haskell, que invoca main. También hay unsafePerformIO, por supuesto. Si desea pensar que la Maybemónada tiene una "máquina al final de la cinta transportadora", puede usarla maybe.
Benjamin Hodgson
1
Pero, dando la vuelta a su explicación, cuando desee producir un valor comonádico al comienzo de una cadena de cobindaplicaciones, debe haber alguna función que haga algo útil con la representación interna de su comonad.
Benjamin Hodgson
2
La instancia específica de comonad o mónada claramente puede tener más funcionalidad de la requerida solo para implementar las clases de tipos
jk.
2
No es que esto sea útil si no aborda esta pregunta desde el lado teórico / matemático de categoría, pero quería señalar que una comonad no es lo inverso, sino más bien el dual de una mónada.
Jörg W Mittag

Respuestas:

11

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 de objects(de cualquier tipo o naturaleza, la estructura interna es irrelevante) y algunas arrowsentre 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 un opposite categorysimplemente 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 y IObservable<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, donde Task<U> ContinueWith<U>(Func<Task<T>, U>)sería el dual de bind(o SelectManycomo se llama en C #)

sara
fuente