Una cosa che lo confonde è che le funzioni "popolari" piacciono binde <*>sono orientate alla prassi. Ma per capire i concetti è più facile guardare prima altre funzioni. Vale anche la pena notare che le monadi si distinguono perché sono un po 'overhyped rispetto ad altri concetti collegati. Quindi inizierò con i funzione.
I Functor offrono una funzione (nella notazione di Haskell) fmap :: (Functor f) => (a -> b) -> f a -> f b. In altre parole, hai un contesto in fcui puoi sollevare una funzione. Come puoi immaginare, quasi tutto è un funzione. Elenchi, forse, entrambe le funzioni, I / O, tuple, parser ... Ognuno rappresenta un contesto in cui può apparire un valore. Quindi puoi scrivere funzioni estremamente versatili che funzionano in quasi ogni contesto usando fmapo la sua variante in linea <$>.
Quali altre cose vuoi fare con i contesti? Potresti voler combinare due contesti. Così si potrebbe desiderare di ottenere una generalizzazione zip :: [a] -> [b] -> [(a,b)]per esempio come questo: pair :: (Monoidal f) => f a -> f b -> f (a,b).
Ma poiché è ancora più utile nella pratica, le librerie Haskell invece offrono Applicative, che è una combinazione di Functore Monoidal, e anche di Unit, che aggiunge semplicemente che puoi effettivamente mettere i valori "dentro" il tuo contesto unit.
Puoi scrivere funzioni estremamente generiche semplicemente affermando queste tre cose sul contesto in cui stai lavorando.
Monadè solo un'altra cosa che puoi affermare in più. Quello che non ho menzionato prima è che hai già due modi per combinare due contesti: non solo puoi pair, ma puoi anche impilarli, ad esempio puoi avere un elenco di elenchi. Nel contesto I / O, un esempio potrebbe essere un'azione I / O in grado di leggere altre azioni I / O da un file, quindi si avrà un tipo FilePath -> IO (IO a). Come possiamo liberarci di quello stacking per ottenere una funzione eseguibile IO a? Ecco dove arriva Monads join, ci permette di combinare due contesti sovrapposti dello stesso tipo. Lo stesso vale per i parser, forse ecc. Ed bindè solo un modo più pratico da usarejoin
Quindi un contesto monadico deve offrire solo quattro cose e può essere utilizzato con quasi tutti i macchinari sviluppati per l'I / O, per i parser, per i guasti, ecc.