religion obras monadas leibniziano leibniz las educatina doctrina biografia haskell compiler-construction semantics monads

haskell - obras - leibniziano



¿Qué te sucede si rompes las leyes de la mónada? (3)

¿El compilador o las partes más "nativas" de las bibliotecas (IO o funciones que tienen acceso a la magia negra y la implementación) hacen suposiciones sobre estas leyes? ¿Romperlos hará que ocurra lo imposible?

¿O simplemente expresan un patrón de programación, es decir, la única persona a la que molestará si los rompe son las personas que usan su código y no esperan que sea tan descuidado?


El compilador no hace suposiciones sobre las leyes, sin embargo, si su instancia no obedece las leyes, no se comportará como una mónada: hará cosas extrañas y, de otro modo, parecerá que sus usuarios no funcionan correctamente (p. Ej. valores, o evaluar cosas en el orden incorrecto).

Además, las refactorizaciones que sus usuarios puedan hacer asumiendo que las leyes de mónadas se mantengan obviamente no serán sólidas.


Para las personas que trabajan en lenguajes más "convencionales", esto sería como implementar una interfaz, pero hacerlo de manera incorrecta. Por ejemplo, imagina que estás usando un marco que ofrece una interfaz IShape y lo implementas. Sin embargo, su implementación del método draw () no dibuja en absoluto, sino que crea instancias de 1000 instancias más de su clase.

El marco trataría de usar su IShape y hacer cosas razonables con él, y Dios sabe lo que sucedería. Sería una especie de choque de trenes interesante de ver.

Si dice que es una mónada, está "declarando" que cumple con su contrato y sus leyes. Otro código creerá su declaración y actuará en consecuencia. Como mentiste, las cosas saldrán mal de manera imprevista.


Las leyes de mónada son simplemente reglas adicionales que se espera que sigan las instancias, más allá de lo que se puede expresar en el sistema de tipos. En la medida en que Monad expresa un patrón de programación, las leyes son parte de ese patrón. Dichas leyes se aplican también a otras clases de tipos: Monoid tiene reglas muy similares a Monad , y generalmente se espera que las instancias de Eq sigan las reglas esperadas para una relación de igualdad, entre otros ejemplos.

Debido a que estas leyes son, en cierto sentido, "parte" de la clase de tipo, debería ser razonable que otros códigos esperen que se mantengan y actúen en consecuencia. Las instancias que se comportan mal pueden, por lo tanto, violar las suposiciones hechas por la lógica del código del cliente, lo que da como resultado errores, cuya culpa es colocada correctamente en la instancia, no el código que la usa.

En resumen, "romper las leyes de la mónada" generalmente debería leerse como "escribir código erróneo".

Ilustraré este punto con un ejemplo que involucra a otra clase de tipo, modificado a partir de uno dado por Daniel Fischer en la lista de correo de haskell-cafe. Es (afortunadamente) bien conocido que las bibliotecas estándar incluyen algunas instancias que se comportan mal, concretamente Eq y Ord para tipos de coma flotante. La mala conducta ocurre, como se puede adivinar, cuando NaN está involucrado. Considere la siguiente estructura de datos:

> let x = fromList [0, -1, 0/0, -5, -6, -3] :: Set Float

Donde 0/0 produce un NaN, que viola las suposiciones sobre las instancias de Ord realizadas por Data.Set.Set . ¿Este Set contiene 0 ?

> member 0 x True

Sí, por supuesto que sí, ¡está ahí a plena vista! Ahora, insertamos un valor en el Set :

> let x'' = insert (0/0) x

Este Set todavía contiene 0 , ¿verdad? No eliminamos nada, después de todo.

> member 0 x'' False

... oh . Oh querido.