coldwa.st
Todas las guíasProgramaciónWebDatosHerramientasBases de datosHaskellConceptosCabal y buildsToolchainCompiladorRendimientoEditor y HLS

Haskell · conceptos · mónadas

Las mónadas en Haskell, explicadas sin jerga

Por ColdwastActualizado el 14 de junio de 20268 min de lectura#haskell#monads#concepts
Código fuente abierto en un editor de código
Las mónadas son el patrón que Haskell usa para secuenciar cómputos que llevan contexto.

"Mónada" tiene una reputación temible que no se merece. Despojada de la jerga, una mónada en Haskell no es más que un tipo que te permite secuenciar cómputos que llevan cierto contexto — un posible fallo, un efecto secundario, múltiples resultados — sin escribir el cableado a mano cada vez. Esta guía explica qué es realmente una mónada, las dos operaciones que la definen, la notación do y las mónadas de cada día que ya usas.

La idea en una frase

Una mónada es un tipo con una forma de encadenar pasos en los que cada paso depende del resultado del anterior, y el "contexto" (fallo, efectos, no determinismo) se hila automáticamente a través de ellos. Eso es todo. Los famosos tipos Maybe, Either, IO y listas son mónadas porque cada uno define ese encadenamiento para su propia clase de contexto.

Las dos operaciones

La clase de tipos Monad se define mediante dos funciones:

return :: a -> m a          -- wrap a plain value into the monad
(>>=)  :: m a -> (a -> m b) -> m b   -- "bind": feed the result into the next step

>>= (que se pronuncia "bind") es el corazón del asunto: toma un valor en contexto y una función que produce el siguiente valor en contexto, y los cose juntos — gestionando el contexto por ti.

La notación do: lo mismo, pero legible

Código fuente en la pantalla de un ordenador
Código fuente en una pantalla — la notación do es azúcar sintáctico sobre el operador bind.

Los bloques do son solo azúcar sobre >>=. Estos son equivalentes:

-- with bind
getLine >>= \name -> putStrLn ("Hi " ++ name)

-- with do-notation
do name <- getLine
   putStrLn ("Hi " ++ name)

La notación do te permite escribir código secuenciado que lleva contexto y que se lee como pasos imperativos, manteniéndose a la vez puramente funcional.

Las mónadas que ya usas

  • Maybe — el contexto es "podría estar ausente". Bind cortocircuita en Nothing, así que encadenas búsquedas sin comprobaciones de nulos anidadas.
  • Either — el contexto es "podría fallar con un error". Como Maybe pero lleva el porqué del fallo.
  • IO — el contexto es "realiza efectos secundarios". La mónada IO es la forma en que Haskell secuencia efectos manteniéndose pura; main :: IO () es el punto de entrada.
  • Lista ([]) — el contexto es "múltiples resultados". Bind explora todas las combinaciones (no determinismo).

Has estado usando mónadas desde tu primer main — IO es una.

Por qué importan las mónadas

Te permiten abstraer el cableado de la gestión de fallos, los efectos y la secuenciación en un patrón reutilizable, de modo que el mismo código en estilo do funciona en contextos muy distintos. Por eso Haskell puede mantener IO separado y explícito sin dejar de ser ergonómico. Para ejecutar todo esto necesitas el toolchain — consulta cómo instalar Haskell con GHCup y la guía del compilador GHC, y prueba los ejemplos en vivo en GHCi.

Preguntas frecuentes

¿Qué es una mónada en términos sencillos? Un tipo que te permite encadenar cómputos que llevan contexto (fallo, efectos, múltiples resultados), hilando ese contexto automáticamente mediante el operador bind.

¿Es IO una mónada? Sí — IO es la mónada que Haskell usa para secuenciar efectos secundarios manteniéndose pura. Tu main se ejecuta en ella.

¿Necesito entender la teoría de categorías? No. Puedes usar mónadas de forma productiva en Haskell conociendo solo return, >>= y la notación do; la teoría es opcional.

¿Cuál es la diferencia entre Maybe y Either? Ambas modelan un posible fallo; Maybe solo dice "ausente" (Nothing), mientras que Either lleva un valor de error que explica el fallo.

Guía independiente y mantenida por la comunidad. coldwa.st es un sitio de recursos de programación; este artículo es texto explicativo nuevo y original sobre las mónadas de Haskell, no afiliado a ningún proyecto ni escrito por él. El código refleja el comportamiento estándar de Haskell — verifícalo con la documentación actual de GHC.