Solitamente le cose di monad sono più facili da comprendere quando si inizia con le monadi "collezione-like" come esempio. Immagina di calcolare la distanza di due punti:
data Point = Point Double Double
distance :: Point -> Point -> Double
distance p1 p2 = undefined
Ora potresti avere un determinato contesto. Per esempio. uno dei punti potrebbe essere "illegale" perché è fuori da alcuni limiti (ad esempio sullo schermo).Quindi avvolgere il vostro calcolo esistente nel Maybe
Monade:
distance :: Maybe Point -> Maybe Point -> Maybe Double
distance p1 p2 = undefined
Hai esattamente lo stesso calcolo, ma con la caratteristica aggiuntiva che ci possa essere "nessun risultato" (codificato come Nothing
).
Oppure si dispone di due gruppi di punti "possibili", e hanno bisogno delle loro reciproche distanze (per esempio utilizzare in seguito la connessione più breve). Poi la lista monade è la tua "contesto":
distance :: [Point] -> [Point] -> [Double]
distance p1 p2 = undefined
O i punti vengono inseriti da un utente, che rende il calcolo "deterministica" (nel senso che si contano su cose nel mondo esterno, che può cambiare), quindi la monade IO
è tuo amico:
distance :: IO Point -> IO Point -> IO Double
distance p1 p2 = undefined
il calcolo rimane sempre lo stesso, ma succede che si terrà in un determinato "contesto", che aggiunge alcuni aspetti utili (fallimento, più valori, non determinismo) . Puoi persino combinare questi contesti (trasformatori monad).
Si può scrivere una definizione che unifica le definizioni di cui sopra, e lavora per qualsiasi monade:
distance :: Monad m => m Point -> m Point -> m Double
distance p1 p2 = do
Point x1 y1 <- p1
Point x2 y2 <- p2
return $ sqrt ((x1-x2)^2 + (y1-y2)^2)
che dimostra che il nostro calcolo è davvero indipendenti dalla monade reale, che porta a formulazioni come "x è calcolato in (-side) la y monade".
Oggigiorno preferisco riferirmi a questi come * azioni * o * calcoli *. Se sono prodotti da una funzione, potresti parlare di azioni parametriche o di funzioni monadiche, ma quest'ultimo termine è ambiguo. Potrebbe riferirsi a 'a -> m b', ma anche a' m (a -> b) '. Poiché quest'ultimo è usato in stile applicativo, preferisco un termine meno ambiguo. – ertes
Assicurati di non perdere la risposta di C. A. McCann sotto. – ertes