Monade (informatica)
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[1]:
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
Storia
[modifica | modifica wikitesto]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.
Caratteristiche
[modifica | modifica wikitesto]Formalmente, una monade può essere espressa come un monoide nella categoria degli endofuntori[2].
Una monade può essere descritta come una tripla :
- : rappresenta la tipologia del costrutto, ad esempio nella monade IO, T sarà uguale a IO.
- : (eta) è una funzione tale che permette il passaggio da a -> T a, quindi equivarrebbe alla funzione
return
in Haskell; - : (mu) è un'altra funzione che permette la concatenazione o la composizione di monadi della stessa tipologia, utilizzata in Haskell attraverso l'operatore
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 [3]. Durante l'elencazione delle caratteristiche, saranno usate delle funzioni:
- la funzione
return
rappresenta la funzione di identità[4]; - l'operatore
bind (>>=)
rappresenta la funzione di composizione di due monadi.
Primo assioma - Leggi dell'identità
[modifica | modifica wikitesto]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
Secondo assioma - Legge dell'associatività
[modifica | modifica wikitesto]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
Note
[modifica | modifica wikitesto]- ^ Definizione della classe Monade in Haskell
- ^ (EN) Saunders Mac Lane, Categories for the Working Mathematician, 1971.«a monad in X is just monoid in the category of endofunctors»
- ^ Haskell è stato uno dei primi linguaggi ad implementare le Monadi in modo comprensibile e ricco di documentazione.
- ^ La funzione identità (return), deve essere implementata in base alla tipologia del costrutto della Monade specifica.
Bibliografia
[modifica | modifica wikitesto]- (EN) Graham Hutton, Programming in Haskell, Cambridge University Press, 2007, ISBN 978-0-521-69269-4.
- (EN) Simon Peyton Jones, Haskell 98 Language and Libraries - The Revised Report, 1999.
- (EN) Eugenio Moggi, Notions of computation and monads, in Information and Computation, vol. 93, n. 1, 1º luglio 1991, pp. 55–92, DOI:10.1016/0890-5401(91)90052-4.
Voci correlate
[modifica | modifica wikitesto]Collegamenti esterni
[modifica | modifica wikitesto]- (EN) Denis Howe, monad, in Free On-line Dictionary of Computing. Disponibile con licenza GFDL
Miscellanea
[modifica | modifica wikitesto]- (EN) Haskell Wiki (4 settembre 2015), "All About Monads", un tutorial ricco di esempi e suggerimenti su come utilizzare le monadi, ma che non spiega quasi niente a livello formale.
- (EN) Haskell Wiki (13 luglio 2015), "Monads", un'introduzione basilare sulle monadi in Haskell.
- (EN) Brian Beckman, "Don't Fear Monads", una spiegazione delle monadi utilizzando concetti matematici base.