Usar mónadas es mucho más fácil de lo que crees, empezando con la programación funcional

Probablemente todos tenemos formada una gran idea sobre lo que es una propiedad, un procedimiento estático, un singleton o bien otros términos de empleo común. Nos resultan algo más exóticos y también inusuales términos como clase abstracta o bien función virtual pura. Todos estos son términos frecuentes en la programación orientada a objetos. Lo que probablemente ya no tengamos tan claras son todas y cada una de las ramificaciones, implicaciones, interactúes que todos estos conceptos tienen y no obstante los utilizamos. Emplear una mónada es tanto o bien más simple de utilizar que, por servirnos de un ejemplo, un objeto. Mas una mónada no es un objeto, y quien desee entender de qué forma utilizar una mónada deberá hacer el ahínco por desprenderse de viejas y repantigadas preconcepciones.

¿Qué es una mónada?

Una mónada está bien definida. Podemos utilizar la definición de la fotografía de la portada si deseamos adquirir las profundas y sensatas implicaciones que las mónadas tienen (y que ignoro por incapacidad manifiesta) o podemos emplear otra más útil y pragmática como la utilizada en diferentes lenguajes de programación y particularmente la de Haskell. No obstante, para aprender informalmente lo que es una mónada, creo que es un fallo tomar como base la definición de mónada, la que solo es útil cuando ya se está cómodo empleándolas.

¿A qué huelen las mónadas?

Huelen a contexto. Cuando estás tumbado en el sofá de tu casa, estás en un contexto. Cuando conduces, estás en un contexto. Cuando estás buceando en el mar, estás en un contexto. De este modo, podríamos decir que las mónadas son contextos:

dormirLaSiesta :: Sofá ()
dormirLaSiesta = …

regresarAlFuturo :: DeLoreanDMC12 ()
regresarAlFuturo = …

brazada :: Buceando ()
brazada = …

Por consiguiente, una mónada es simple de emplear mas lo más esencial es que es segura de utilizar por el hecho de que no habría ningún inconveniente en que te quedases dormido en el sofá, mas sí catastrófico si te da por dormirte en el turismo o bien mientras que buceas.

irAlPueblo :: DeLoreanDMC12 ()
irAlPueblo = do

encenderMotor
meterPrimera
apresurar
dormirLaSiesta — afortunadamente no compila

No veas posibles semejanzas con los objetos. Un objeto resguarda sus datos y define sus métodos, mas no controla quién ni de qué manera es utilizado y es difícilmente extensible (ej. mixings). Una mónada controla quién y de qué manera es utilizada, no solo resguarda posibles datos, sino más bien todo el contexto en que se ejecuta y es trivial y necesariamente extensible.

¿Para qué valen las mónadas?

Simplemente para acotar una computación un proceso que se ejecuta en un contexto. El ejemplo precedente irAlPueblo es un fácil ejemplo, pongamos ahora otro más interesante.

Supón que tenemos 3 contextos situaciones absolutamente diferentes:

una lista de números.
un solo número mas que quizá esté o bien no definido (el habitual opcional).
un teletipo por el que un usuario introduce números.

Para cada situación, debemos incorporar un proceso que sume dos a los números implicados. Esto es, el contexto con la lista de números se transformará en un contexto con los números aumentados en 2 unidades, el contexto que tal vez tiene o bien no un número se va a ver aumentado o bien no en 2 unidades y los números que el usuario introduce por el teletipo se van a ver aumentados en 2.

suma2_lista :: Lista Número -> Lista Número
suma2_lista lista = …

suma2_quizás :: Quizá Número -> Tal vez Número
suma2_quizás tal vez = …

suma2_teletipo :: Teletipo Número -> Teletipo Número
suma2_teletipo teletipo = …

¿De qué forma incorporarías los 3 procesos que te han pedido?, ¿qué diferencias hay entre unos y otros?.

A la inversa de lo que ocurría con dormir la siesta en que una acción sí podía efectuarse en un contexto mas no en otros, acá es exactamente exactamente el mismo proceso el que puede realizarse en cualquiera de los 3 procesos mas, ¿como es entonces el contexto sobre el que definiremos nuestro proceso?, ¿qué nombre tiene o bien como se define un contexto que al unísono sea una lista, un tal vez y un teletipo?. Veámoslo:

suma2 :: Mónada m => m Número -> m Número
suma2 cosa_que_devuelve_números = …

En sitio de precisar la mónada el contexto sobre el que sumaremos, afirmamos que nos sirve cualquier mónada cosa que devuelva números. Ahora, las 3 funciones precedentes son precisamente la nueva función suma2 y verdaderamente no las precisamos por el hecho de que los 3 procesos pedidos son:

> suma2 [1..5]
[3,4,5,6,7]
> suma2 (Just diez)
Just doce
> suma2 Nothing
Nothing
> suma2 (putStr Número: >> readLn)
Número: treinta y cuatro
treinta y seis

Procesos sobre las mónadas

Ya podemos comenzar a acotar un tanto mejor esto de las mónadas y para esto, solamente precisamos introducir 2 símbolos:

el símbolo que, dado un contexto, me devuelve algo. Por poner un ejemplo si estoy en el vehículo, deseo conseguir la velocidad actual, entonces deberá haber una función como dameVelocidad que en algún lugar (afirmemos variable) me entregue esa velocidad.
el símbolo con el que devuelvo el resultado de mi definición. Por servirnos de un ejemplo si paso la velocidad de kilómetros/hora a millas/hora, tras hacer la conversión deberé devolver el resultado.

Veamos los símbolos con un ejemplo:

— Esta nos la dan de serie con el turismo
velocidadEnKilómetrosHora :: DeLoreanDMC12 KilómetrosHora

— Deseamos transformar de Quilómetros a Millas
velocidadEnMillasHora :: DeLoreanDMC12 MillasHora
velocidadEnMillasHora = do
kmh m Número -> m Número
suma2 algo_que_devuelve_números = do
x