simbolo significado significa quiere que percepcion mónada monadología monada leibniz etimologico espiritual decir apeticion design-patterns haskell monad-transformers monads

design-patterns - significado - que significa monada wikipedia



¿Alguna vez alguien se ha encontrado con un Transformador de Mónada en la naturaleza? (6)

En mi área de negocios - back office IT para una institución financiera - es muy común que un componente de software lleve una configuración global, registrar su progreso, tener algún tipo de error en el manejo / cortocircuito de computación ... Cosas que puede ser modelado muy bien por Reader-, Writer-, Maybe-mónadas y similares en Haskell y compuesto junto con transformadores de mónada.

Pero parece que hay algunos inconvenientes: el concepto detrás de los transformadores de mónada es bastante complicado y difícil de entender, los transformadores de mónada conducen a firmas de tipo muy complejas, e infligen una cierta penalización en el rendimiento.

Así que me pregunto: ¿son las mejores prácticas de los transformadores de mónadas cuando se trata de las tareas comunes mencionadas anteriormente?


Creo que esto es un error, solo que la món IO no es pura. Las mónadas como las mónadas Write / T / Reader / T / State / T / ST son puramente funcionales.

Me parece que hay más de una noción sobre el término puro / no puro. Su definición "IO = unpure, todo lo demás = puro" suena similar a lo que Peyton-Jones habla en "Efectos de domesticación" ( http://ulf.wiger.net/weblog/2008/02/29/peyton-jones-taming-effects-the-next-big-challenge/ ). Por otro lado, el Real World Haskell (en las páginas finales del capítulo Monad Transformer) contrasta funciones puras con funciones monádicas en general, argumentando que se necesitan bibliotecas diferentes para ambos mundos. Por cierto, uno podría argumentar que IO también es puro, sus efectos secundarios están encapsulados en una función de estado con tipo RealWorld -> (a, RealWorld) . Después de todo, Haskell se llama a sí mismo un lenguaje puramente funcional (IO incluido, supongo :-).)

Mi pregunta no es tanto sobre lo que se puede hacer teóricamente, sino más sobre lo que se ha demostrado que es útil desde el punto de vista de la ingeniería de software. Los transformadores de mónada permiten la modularidad de los efectos (y las abstracciones en general), pero, ¿a dónde debe dirigirse la programación de la dirección?


El concepto detrás de los transformadores de mónada es bastante complicado y difícil de entender, los transformadores de mónada conducen a firmas de tipo muy complejas

Creo que esto es un poco exagerado

  • Usar una pila Monad particular de un transformador no es más difícil de usar que una Monad simple. Solo piensa en layers / stacks y estarás bien. Casi nunca es necesario levantar una función pura (o acción IO específica) más de una vez.
  • Como se mencionó anteriormente, oculte su pila de Monad en un nuevo tipo, use derive generalizado y oculte el constructor de datos en un módulo.
  • Trate de no utilizar una pila Monad particular en la firma del tipo de función, escriba el código general con clases de tipo Monad como MonadIO, MonadReader y MonadState (use la extensión de contextos flexibles que está estandarizada en Haskell 2010).
  • Use librerías como fclabels para reducir las acciones repetitivas que acceden a las partes del registro en una Monad.

Los transformadores de mónada no son sus únicas opciones, puede escribir una Mónada personalizada, usar una Mónada de continuación. Tiene referencias / matrices mutables en IO (global), ST (local y controlado, sin acciones IO), MVar (sincronización), TVar (transaccional).

He escuchado que los posibles problemas de eficiencia con los transformadores Monad podrían mitigarse simplemente agregando pines INLINE para enlazar / regresar a la fuente de la biblioteca mtl / transformers.


Entonces, ¿algo que tiende a ser más bien global como un registro o una configuración, sugeriría poner en la mónada IO? Al observar ejemplos (un conjunto ciertamente muy limitado), llego a pensar que el código Haskell tiende a ser puro (es decir, no monádico) o en la mónada IO. ¿O es esto una idea errónea?

Creo que esto es un error, solo que la món IO no es pura. Las mónadas como las mónadas Write / T / Reader / T / State / T / ST son puramente funcionales. Puedes escribir una función pura que use cualquiera de estas mónadas internamente como este ejemplo completamente inútil:

foo :: Int -> Int foo seed = flip execState seed $ do modify $ (+) 3 modify $ (+) 4 modify $ (-) 2

Todo lo que está haciendo es enhebrar / sondear el estado implícitamente, lo que haría usted mismo a mano explícitamente, la notación do aquí simplemente le da un buen azúcar sintáctico para que se vea imperativo. No puede hacer ninguna acción IO aquí, no puede llamar a ninguna función extranjera. ST monad le permite tener referencias reales mutables en un ámbito local mientras tiene una interfaz de función pura y, no puede hacer ninguna acción de E / S allí, es puramente funcional.

No puede evitar algunas acciones de E / S, pero no quiere volver a recurrir a E / S para todo, porque allí es donde todo puede ir, se pueden lanzar misiles, no tiene control. Haskell tiene abstracciones para controlar cómputos efectivos en diversos grados de seguridad / pureza, la mónada IO debería ser el último recurso (pero no se puede evitar por completo).

En su ejemplo, creo que debe seguir utilizando transformadores de mónada o una mónada hecha a medida que haga lo mismo que componerlos con transformadores. Nunca he escrito una mónada personalizada (todavía) pero he usado bastante transformadores de mónada (mi propio código, no en el trabajo), no se preocupe tanto por ellos, úselos y no es tan malo como cree .

¿Has visto el capítulo de Real World Haskell que usa transformadores de mónada ?


Cuando estaba aprendiendo mónadas, construí una aplicación usando una pila de StateT ContT IO para crear una biblioteca de simulación de eventos discretos; las continuaciones se usaron para almacenar subprocesos monádicos, con StateT conteniendo la cola de subprocesos ejecutables y otras colas usadas para subprocesos suspendidos esperando varios eventos. Funcionó bastante bien No pude entender cómo escribir la instancia de Monad para un contenedor de tipo nuevo, así que lo convertí en un sinónimo de tipo y funcionó bastante bien.

En estos días probablemente habría rodado mi propia mónada desde cero. Sin embargo, cada vez que hago esto, me encuentro mirando "All About Monads" y la fuente del MTL para recordarme cómo son las operaciones de vinculación, así que en cierto sentido sigo pensando en términos de una pila de MTL aunque el resultado es una mónada personalizada


Recientemente "caí" en la composición de la mónada en el contexto de F #. Escribí una DSL con una fuerte dependencia de la mónada de estado: todos los componentes dependen de la mónada de estado: el analizador (mónada de analizador basada en mónada de estado), tablas de coincidencia de variables (más de uno para tipos internos), tablas de búsqueda de identificador. Y como todos estos componentes funcionan juntos, dependen de la misma mónada de estado. Por lo tanto, hay una noción de composición del estado que reúne a los diferentes estados locales y la noción de usuarios del estado que le dan a cada algo su propia visibilidad del estado.

Inicialmente, el diseño fue realmente "solo una gran mónada de estado". Pero luego comencé a necesitar estados con solo tiempos de vida locales, y aún así en el contexto del estado "persistente" (y de nuevo, todos estos estados son administrados por mónadas estatales). Para eso tuve que introducir transformadores de mónada de estado que aumentan el estado y adaptan las mónadas de estado juntas. También agregué un transformador para moverme libremente entre una mónada de estado y una mónada de estado de continuación, pero no me he molestado en usarla.

Por lo tanto, para responder a la pregunta: sí, los transformadores de mónada existen en el "salvaje". Sin embargo, yo argumentaría fuertemente en contra de usarlos "fuera de la caja". Escribe tu aplicación con simples bloques de construcción, usando pequeños puentes hechos a mano entre tus módulos, si terminas usando algo así como un transformador de mónada, eso es genial; No empieces desde allí.

Y sobre las firmas de tipo: he llegado a pensar en este tipo de programación como algo muy similar a jugar al ajedrez a ciegas (y no soy ajedrecista): su nivel de habilidad debe ser el punto en que "vea" sus funciones y tipos que encajan entre sí. Las firmas de tipo en su mayoría terminan siendo una distracción, a menos que explícitamente desee agregar restricciones de tipo por razones de seguridad (o porque el compilador le obliga a darlas, como con los registros F #).


La comunidad de Haskell está dividida sobre este tema.

  • John Hughes informa que le resulta más fácil enseñar transformadores de mónadas que enseñar mónadas, y que a sus alumnos les va mejor con un enfoque de "transformadores primero".

  • Los desarrolladores de GHC generalmente evitan los transformadores de mónada, y prefieren enrollar sus propias mónadas que integran todas las características que necesitan. (Me dijeron que hoy en términos muy claros que GHC no usará un transformador de mónada que definí hace tres días).

Para mí, los transformadores de mónada son muy parecidos a la programación sin puntos (es decir, programación sin variables nombradas), lo que tiene sentido; después de todo, están programando exactamente sin puntos en el nivel de tipo. Nunca me gusta la programación sin puntos porque es útil poder introducir el nombre ocasional.

Lo que observo en la práctica es

  • El número de transformadores de mónada disponibles en Hackage es muy bueno, y la mayoría de ellos son bastante simples. Esta es una instancia clásica del problema donde es más difícil aprender una biblioteca grande que rodar sus propias instancias.

  • Mónadas como Writer, State y Environment son tan simples que no veo mucho beneficio para los transformadores de mónada.

  • Donde los transformadores mónada brillan es en modularidad y reutilización. Esta propiedad está bellamente demostrada por Liang, Hudak y Jones en su documento histórico "Monad Transformers and Modular Interpreters" .

¿Son las mejores prácticas de los transformadores de mónada cuando se trata de las tareas comunes mencionadas anteriormente?

Yo diría que no. Donde los transformadores de mónadas son la mejor práctica es donde tienes una línea de productos de abstracciones relacionadas que puedes crear componiendo y reutilizando transformadores de mónada de diferentes maneras. En un caso como este, probablemente desarrolle una cantidad de transformadores de mónadas que son importantes para su dominio problemático (como el que fue rechazado para GHC) y usted (a) los compone de múltiples maneras; (b) lograr una cantidad significativa de reutilización para la mayoría de los transformadores; (c) están encapsulando algo no trivial en cada transformador de mónadas.

Mi transformador de mónada que fue rechazado por GHC no cumplió con ninguno de los criterios (a) / (b) / (c) anteriores.