Nella programmazione funzionale, una monade è una struttura che esprime una classe di computazioni concatenabili.
Con l'ausilio di questa struttura, è possibile compiere, anche nei linguaggi puramente funzionali, operazioni in sequenza, un po' come avviene nei linguaggi imperativi o procedurali. Infatti, possono essere espresse, con l'ausilio delle monadi, fenomeni come gli effetti collaterali, l'IO, gestione dell'eccezioni.
In Haskell, la classe Monad viene espressa come segue:
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b -- non strettamente necessaria
return :: a -> m a
fail :: String -> m a -- non strettamente necessaria
Negli anni sessanta, alcuni linguaggi di programmazione, come J e APL, i quali tendevano a essere dei linguaggi puramente funzionali, utilizzavano il termine monade per indicare le funzioni che avevano un solo parametro di input. Questo termine si contrapponeva a quello di diade, cioè tutte quelle funzioni aventi due parametri invece che solo uno. Come si vedrà più avanti, con monade si identificheranno delle strutture completamente diverse.
Infatti, nel 1991, Eugenio Moggi, professore di Informatica all'Università degli Studi di Genova, pubblicò un saggio, nel quale considerava l'utilizzo della monade, attraverso la semantica del Lambda calcolo, per gestire gli effetti collaterali, gli input e gli output, le eccezioni e altro. Questa pubblicazione ha influito sul lavoro di molti informatici, tra i quali Simon Peyton Jones, il quale, poi le implementerà nel linguaggio puramente funzionale Haskell (al posto di utilizzare delle lazy-list per gestire l'IO).
Per molto tempo, l'utilizzo di queste strutture, è stato ristretto a una piccolissima cerchia di linguaggi, molti dei quali puramente funzionali (soprattutto a causa dei problemi legati alla gestione dell'IO). Di recente, queste strutture sono state adattate anche ai linguaggi imperativi, per lo più per permettere l'utilizzo di alcuni pattern della programmazione funzionale che sono più facilmente comprensibili e facili da scrivere. Alcuni di questi linguaggi, sono Python, Scala, Perl, Racket e Java. Oltre ai linguaggi imperativi e puramente funzionali, anche i linguaggi della famiglia ML, come F#, si stanno evolvendo per permettere l'utilizzo delle monadi.
Formalmente, una monade può essere espressa come un monoide nella categoria degli endofuntori.
Una monade può essere descritta come una tripla :
return in Haskell;bind (>>=);Come si può notare dalla descrizione data sopra, le funzioni "proprie" di una monade sono due. Proprio su queste due, si basano le leggi che ogni monade deve seguire per permettersi di avere le sue caratteristiche.
Le due leggi, verranno espresse in Haskell. Durante l'elencazione delle caratteristiche, saranno usate delle funzioni:
return rappresenta la funzione di identità;bind (>>=) rappresenta la funzione di composizione di due monadi.Deve esistere un elemento tale che composto a una funzione, essa dia come risultato la funzione con cui è stato composto il membro neutro. Questa caratteristica deve possedere la proprietà commutativa.
-- identità a destra:
f >>= return == f
-- identità a sinistra:
return a >>= f == f a
-- dalla versione 2010 del linguaggio è anche
-- possibile scriverla con la notazione do:
-- identità a 'destra':
do x <- m
return x
= m
-- con l'identità a 'sinistra':
do y <- return x
f y
= do f x
Un insieme di tre funzioni, possono essere combinate in due modi equivalenti.
(f >>= g) >>= h == f >>= (\x -> g x >>= h)
-- esprimibile con la notazione do, nel modo seguente
do b <- do a <- m
f a
g b
= do a <- m
b <- f a
g b
= do a <- m
do b <- f a
g b