¿Qué problemas de programación resuelven las mónadas? [cerrado]

14

He leído un montón de publicaciones que explican qué son las mónadas, cómo funcionan unit y bind , algunas de ellas se sumergen directamente en la teoría de categorías tan abstracta (al menos para mí) que hace sangrar los ojos, otras ignorando todo eso y tocando extrañas analogías de burritos, cajas y lo que no.

Después de unas pocas semanas de estudio y muchas neuronas fritas, (creo) entiendo cómo funcionan las mónadas. Pero todavía hay una cosa que se me escapa, algo que pocas publicaciones realmente tocan (excepto IO y estado):

¿POR QUÉ?

¿Por qué importan las mónadas? ¿Por qué son tan importantes? ¿Cuáles son los problemas que están resolviendo? ¿Esos problemas solo se pueden resolver con mónadas o existen otras formas?

    
pregunta Dummy Me 28.02.2016 - 15:44

4 respuestas

10

Usted no necesita mónadas para resolver nada. Simplemente hacen ciertas cosas más simples. Mucha gente va demasiado abstracta y teórica al explicar las mónadas. En su mayoría, las mónadas son un patrón que aparece una y otra vez en la programación. Al reconocer ese patrón, podemos simplificar nuestro código y evitar la reimplementación de ciertas funciones.

Para Haskell, desde un punto de vista concreto, la cosa más visible que permiten las mónadas es hacer notación . Enumere las comprensiones en Haskell y otros idiomas también aproveche las mónadas. También puede crear bibliotecas como Control.Monad .

Todos estos proporcionan simplificaciones útiles, y una vez que lo has implementado para una mónada, lo obtienes automáticamente para todas las mónadas. Esta es una de las razones principales por las que la reutilización del código es mucho más fácil para la programación funcional que otros paradigmas.

    
respondido por el Karl Bielefeldt 28.02.2016 - 19:18
5

Es más fácil de entender si observas las mónadas particulares y ves qué problemas resuelven. Por ejemplo, en Haskell:

  • IO: permite que IO se represente en el sistema de tipos, para que pueda despejar Separe las funciones puras de las funciones que realizan IO.

  • Lista: le permite hacer listas de comprensión y nodeterminista cálculos.

  • Tal vez: una mejor alternativa a los nulos, y apoyar algo comparable al operador de unión nula de C #.

  • Parsec: un DSL conveniente para escribir analizadores.

Por lo tanto, es fácil (espero) ver el razonamiento de las mónadas individuales, ya que son bastante útiles. Pero los problemas que resuelven también son bastante diferentes y, a primera vista, no parecen tener mucho en común, excepto que todos están relacionados con alguna lógica para encadenar operaciones. Las mónadas son útiles porque te permiten construir una variedad de herramientas.

¿Podrían implementarse los ejemplos anteriores sin mónadas? Ciertamente, podrían implementarse de manera ad hoc, pero tener mónadas integradas en el lenguaje permite el soporte directo de lenguaje como la notación do que funciona con todas las mónadas.

    
respondido por el JacquesB 29.02.2016 - 08:22
2

Una cosa que lo hace confuso es que las funciones "populares" como bind y <*> están orientadas a la praxis. Pero para entender los conceptos es más fácil mirar otras funciones primero. También vale la pena destacar que las mónadas se destacan porque están un poco sobrevaloradas en comparación con otros conceptos conectados. Así que empezaré con los funtores en su lugar.

Los

Functors ofrecen una función (en notación Haskell) fmap :: (Functor f) => (a -> b) -> f a -> f b . En otras palabras, tiene un contexto f en el que puede elevar una función. Como puedes imaginar casi cualquier cosa es un funtor. Listas, Tal vez, Cualquiera de las funciones, E / S, tuplas, analizadores ... Cada una representa un contexto en el que puede aparecer un valor. Por lo tanto, puede escribir funciones extremadamente versátiles que funcionan en casi cualquier contexto utilizando fmap o su variante en línea <$> .

¿Qué otras cosas quieres hacer con los contextos? Es posible que desee combinar dos contextos. Por lo tanto, es posible que desee obtener una generalización de zip :: [a] -> [b] -> [(a,b)] , por ejemplo, como este: pair :: (Monoidal f) => f a -> f b -> f (a,b) .

Pero como es aún más útil en la práctica, las bibliotecas de Haskell ofrecen Applicative , que es una combinación de Functor y Monoidal , y también de Unit , que solo agrega que realmente puede poner valores "dentro" de su contexto con unit .

Puedes escribir funciones extremadamente genéricas simplemente declarando estas tres cosas sobre el contexto en el que estás trabajando.

Monad es solo otra cosa que puedes decir sobre eso. Lo que no mencioné antes es que ya tiene dos formas de combinar dos contextos: no solo puede pair ellos, sino que también puede apilarlos, por ejemplo. Puedes tener una lista de listas. En el contexto de E / S, un ejemplo sería una acción de E / S que puede leer otras acciones de E / S de un archivo, por lo que tendría un tipo FilePath -> IO (IO a) . ¿Cómo podemos deshacernos de ese apilamiento para obtener una función ejecutable IO a ? Ahí es donde entra Monad s join , nos permite combinar dos contextos apilados del mismo tipo. Lo mismo ocurre con los analizadores, tal vez etc. Y bind es solo una forma más práctica de usar join

Por lo tanto, un contexto monádico solo tiene que ofrecer cuatro cosas y puede utilizarse con casi toda la maquinaria desarrollada para E / S, analizadores, fallos, etc.

    
respondido por el MarLinn 28.02.2016 - 22:12
1

Mónadas le permite expresar varios cálculos no puros, así como simplificar el código

  • cálculo con estado (obtener / establecer estado a través de la mónada)
  • E / S (registro, UI, archivo o simplemente producir / consumir una lista de X)
  • También, flujo de control "no lineal" (es decir, excepciones, tal vez, etc.)

Y, lo que es más importante, sin comprometer las construcciones de lenguaje puro y obtener un lenguaje más limpio de ellas     

respondido por el Macke 28.02.2016 - 19:54

Lea otras preguntas en las etiquetas