Simplemente no entiendo qué problema resuelven.
haskell
pragmatism
monad
Trabajo
fuente
fuente
Respuestas:
Las mónadas no son buenas ni malas. Ellos simplemente son. Son herramientas que se utilizan para resolver problemas como muchas otras construcciones de lenguajes de programación. Una aplicación muy importante de ellos es facilitar la vida de los programadores que trabajan en un lenguaje puramente funcional. Pero son útiles en lenguajes no funcionales; es solo que la gente rara vez se da cuenta de que está usando una mónada.
¿Qué es una mónada? La mejor manera de pensar en una mónada es como un patrón de diseño. En el caso de E / S, probablemente podría pensar que es poco más que una tubería glorificada donde el estado global es lo que se está pasando entre las etapas.
Por ejemplo, tomemos el código que está escribiendo:
Aquí hay mucho más que lo que parece. Por ejemplo, usted notará que
putStrLn
tiene la firma siguiente:putStrLn :: String -> IO ()
. ¿Por qué es esto?Piénselo de esta manera: imaginemos (por simplicidad) que stdout y stdin son los únicos archivos en los que podemos leer y escribir. En un lenguaje imperativo, esto no es problema. Pero en un lenguaje funcional, no se puede mutar el estado global. Una función es simplemente algo que toma un valor (o valores) y devuelve un valor (o valores). Una forma de evitar esto es usar el estado global como el valor que se transfiere dentro y fuera de cada función. Para que pueda traducir la primera línea de código en algo como esto:
... y el compilador sabría imprimir cualquier cosa que se agregue al segundo elemento de
global_state
. Ahora no sé sobre ti, pero odiaría programar así. La forma en que esto se hizo más fácil fue usar Mónadas. En una mónada, pasa un valor que representa algún tipo de estado de una acción a la siguiente. Es por eso queputStrLn
tiene un tipo de retorno deIO ()
: está devolviendo el nuevo estado global.Entonces, ¿por qué te importa? Bueno, las ventajas de la programación funcional sobre el programa imperativo se han debatido hasta la muerte en varios lugares, por lo que no voy a responder esa pregunta en general (pero vea este documento si desea conocer el caso de la programación funcional). Sin embargo, para este caso específico, podría ayudar si entendiera lo que Haskell está tratando de lograr.
Muchos programadores sienten que Haskell intenta evitar que escriban códigos imperativos o que usen efectos secundarios. Eso no es del todo cierto. Piénselo de esta manera: un lenguaje imperativo es aquel que permite efectos secundarios por defecto, pero le permite escribir código funcional si realmente lo desea (y está dispuesto a lidiar con algunas de las contorsiones que requeriría). Haskell es puramente funcional por defecto, pero le permite escribir código imperativo si realmente lo desea (lo que debe hacer si su programa es útil). El punto no es hacer que sea difícil escribir código que tenga efectos secundarios. Es para asegurarse de que sea explícito acerca de tener efectos secundarios (con el sistema de tipos que lo impone).
fuente
goto
(como argumento para la programación estructurada) un poco más adelante en el documento, caracterizando tales argumentos como "infructuosos". Y sin embargo, ninguno de nosotros secretamente deseagoto
el regreso. Es simplemente que no puede argumentar quegoto
no es necesario para las personas que lo usan ampliamente.¡¡¡Morderé!!! Las mónadas por sí mismas no son realmente una razón de ser para Haskell (las primeras versiones de Haskell ni siquiera las tenían).
Su pregunta es un poco como decir "C ++ cuando miro la sintaxis, me aburro mucho. Pero las plantillas son una característica muy publicitada de C ++, así que miré una implementación en otro lenguaje".
La evolución de un programador Haskell es una broma, no debe tomarse en serio.
Una Mónada para el propósito de un programa en Haskell es una instancia de la clase de tipo Mónada, es decir, es un tipo que soporta cierto conjunto pequeño de operaciones. Haskell tiene soporte especial para tipos que implementan la clase de tipo Monad, específicamente soporte sintáctico. Prácticamente, esto resulta en lo que se ha denominado un "punto y coma programable". Cuando combina esta funcionalidad con algunas de las otras características de Haskell (funciones de primera clase, pereza por defecto), lo que obtiene es la capacidad de implementar ciertas cosas como bibliotecas que tradicionalmente se han considerado características del lenguaje. Puede, por ejemplo, implementar un mecanismo de excepción. Puede implementar el soporte para continuaciones y corutinas como una biblioteca. Haskell, el lenguaje no tiene soporte para variables mutables:
Usted pregunta acerca de "¿Quizás / Identidad / Mónadas División Segura ???". La mónada Quizás es un ejemplo de cómo podría implementar (muy simple, solo una excepción) el manejo de excepciones como una biblioteca.
Tienes razón, escribir mensajes y leer los comentarios de los usuarios no es muy exclusivo. IO es un pésimo ejemplo de "mónadas como característica".
Pero para iterar, una "característica" en sí misma (por ejemplo, Mónadas) aislada del resto del lenguaje no necesariamente parece útil de inmediato (una gran característica nueva de C ++ 0x son las referencias de valor, no significa que pueda tomar fuera del contexto C ++ porque su sintaxis te aburre y necesariamente ve la utilidad). Un lenguaje de programación no es algo que obtienes al lanzar un montón de características en un cubo.
fuente
Todos los programadores escriben programas, pero las similitudes terminan ahí. Creo que los programadores difieren mucho más de lo que la mayoría de los programadores pueden imaginar. Tome cualquier "batalla" de larga data, como escribir variables estáticas frente a tipos de solo tiempo de ejecución, scripting vs compilados, estilo C vs orientado a objetos. Le resultará imposible argumentar racionalmente que un campo es inferior, porque algunos de ellos producen un código excelente en algún sistema de programación que me parece inútil o incluso inutilizable.
Creo que diferentes personas piensan de manera diferente, y si no te sientes tentado por el azúcar sintáctico o especialmente por las abstracciones que solo existen por conveniencia y que en realidad tienen un costo de tiempo de ejecución significativo, entonces mantente alejado de esos idiomas.
Sin embargo, le recomendaría que al menos intente familiarizarse con los conceptos que está renunciando. No tengo nada en contra de alguien que es vehementemente pro-puro-C, siempre y cuando realmente entiendan de qué se trata la expresión lambda. Sospecho que la mayoría no se convertirá inmediatamente en un fanático, pero al menos estará allí en el fondo de sus mentes cuando encuentren el problema perfecto, lo que hubiera sido mucho más fácil de resolver con lambdas.
Y, sobre todo, trata de evitar molestarte con fanboy speak, especialmente por personas que realmente no saben de qué están hablando.
fuente
Haskell impone la transparencia referencial : dados los mismos parámetros, cada función siempre devuelve el mismo resultado, sin importar cuántas veces llame a esa función.
Eso significa, por ejemplo, que en Haskell (y sin Mónadas) no puede implementar un generador de números aleatorios. En C ++ o Java puede hacerlo usando variables globales, almacenando el valor intermedio "semilla" del generador aleatorio.
En Haskell, la contraparte de las variables globales son las mónadas.
fuente
Random
objeto.Es una pregunta vieja, pero es muy buena, así que responderé.
Puede pensar en las mónadas como bloques de código para los que tiene un control completo sobre cómo se ejecutan: qué debe devolver cada línea de código, si la ejecución debe detenerse en algún momento, si debe ocurrir algún otro procesamiento entre cada línea.
Daré algunos ejemplos de cosas que las mónadas permiten que de otra forma serían difíciles. Ninguno de estos ejemplos está en Haskell, solo porque mi conocimiento de Haskell es un poco inestable, pero todos son ejemplos de cómo Haskell ha inspirado el uso de mónadas.
Analizadores
Normalmente, si quisiera escribir un analizador de algún tipo, por ejemplo, para implementar un lenguaje de programación, tendría que leer la especificación BNF y escribir un montón de código de bucle para analizarlo, o tendría que usar un compilador de compilador como Flex, Bison, yacc, etc. Pero con las mónadas, puedes hacer una especie de "analizador de compiladores" directamente en Haskell.
Los analizadores realmente no se pueden hacer sin mónadas o lenguajes especiales como yacc, bison, etc.
Por ejemplo, tomé la especificación del lenguaje BNF para el protocolo IRC :
Y lo redujo a aproximadamente 40 líneas de código en F # (que es otro lenguaje que admite mónadas):
La sintaxis de mónada de F # es bastante fea en comparación con la de Haskell, y probablemente podría haber mejorado esto bastante, pero el punto a tener en cuenta es que, estructuralmente, el código del analizador es idéntico al BNF. Esto no solo habría llevado mucho más trabajo sin mónadas (o un generador de analizadores sintácticos), sino que habría tenido casi ninguna semejanza con la especificación y, por lo tanto, habría sido terrible tanto para leer como para mantener.
Multitarea personalizada
Normalmente, se considera que la multitarea es una característica del sistema operativo, pero con las mónadas, puede escribir su propio planificador de modo que después de cada mónada de instrucciones, el programa pasaría el control al planificador, que luego elegiría otra mónada para ejecutar.
Un tipo hizo una mónada de "tarea" para controlar los bucles del juego (nuevamente en F #), de modo que en lugar de tener que escribir todo como una máquina de estado que actúa en cada
Update()
llamada, podría escribir todas las instrucciones como si fueran una sola función .En otras palabras, en lugar de tener que hacer algo como:
Podrías hacer algo como:
LINQ to SQL
LINQ to SQL es en realidad un ejemplo de una mónada, y una funcionalidad similar podría implementarse fácilmente en Haskell.
No entraré en detalles ya que no recuerdo con tanta precisión, pero Erik Meijer lo explica muy bien .
fuente
Si está familiarizado con los patrones GoF, las mónadas son como el patrón Decorator y el patrón Builder juntos, con esteroides, mordidos por un tejón radiactivo.
Hay mejores respuestas arriba, pero algunos de los beneficios específicos que veo son:
Las mónadas decoran algún tipo de núcleo con propiedades adicionales sin cambiar el tipo de núcleo. Por ejemplo, una mónada podría "levantar" una cadena y agregar valores como "isWellFormed", "isProfanity" o "isPalindrome", etc.
Del mismo modo, las mónadas permiten conglomerar un tipo simple en un tipo de colección
las mónadas permiten la unión tardía de funciones en este espacio de orden superior
las mónadas permiten mezclar funciones y argumentos arbitrarios con un tipo de datos arbitrario, en el espacio de orden superior
las mónadas permiten mezclar funciones puras y sin estado con una base impura y con estado, para que pueda realizar un seguimiento de dónde está el problema
Un ejemplo familiar de una mónada en Java es List. Toma alguna clase de núcleo, como String, y la "eleva" al espacio de mónada de List, agregando información sobre la lista. Luego vincula nuevas funciones en ese espacio como get (), getFirst (), add (), empty (), etc.
A gran escala, imagine que en lugar de escribir un programa, simplemente escribió un gran generador (como el patrón GoF), y el método build () al final escupió cualquier respuesta que se suponía que debía producir el programa. Y que podría agregar nuevos métodos a su ProgramBuilder sin volver a compilar el código original. Es por eso que las mónadas son un modelo de diseño poderoso.
fuente