-
Notifications
You must be signed in to change notification settings - Fork 4
Monades Avancées en Haskell
20. Monade
20.1 Idée de Base (définition sans détails)
20.2 Exemples Intuitifs
20.3 Extraire le Schéma
20.4 Définition Complète (avec tous les détails et lois)
20.5 Notation do en général
21. Monade Reader 21.1 Motivation 21.2 Stratégie de Liaison 21.3 Définition 21.4 Exemples
22. Monade Writer 22.1 Motivation 22.2 Stratégie de Liaison 22.3 Définition 22.4 Exemples
23. Monade State 23.1 Motivation 23.2 Stratégie de Liaison 23.3 Définition 23.4 Exemples
24. Fonctions Monadiques / Travailler avec des Monades
24.1 liftM
24.2 sequence et sequence_
24.3 mapM et mapM_
24.4 filterM
24.5 foldM
25. Transformers
Glossaire des Termes
Questions à Choix Multiples (avec Réponses)
Une monade est un schéma de conception en Haskell qui permet de chaîner des calculs tout en cachant certains soucis comme le contexte, les échecs, l’état ou les effets de bord. Les monades permettent d’écrire du code modulaire qui gère ces préoccupations de manière cohérente. Pensez à une monade comme un « constructeur de calculs » qui relie des étapes entre elles.
Regardons trois monades en action : Maybe, [] (liste) et IO.
Supposons que vous voulez diviser deux nombres, mais gérer la possibilité d'une division par zéro :
safeDiv :: Double -> Double -> Maybe Double
safeDiv _ 0 = Nothing
safeDiv x y = Just (x / y)Utilisation :
result1 = safeDiv 10 2 -- Just 5.0
result2 = safeDiv 10 0 -- NothingExplication :
Maybe est un contexte qui peut représenter une valeur ou « pas de valeur » (Nothing). Cela permet de signaler des erreurs sans lancer d’exception.
Supposons que vous voulez toutes les paires possibles de deux ensembles :
pairs :: [Int] -> [Int] -> [(Int, Int)]
pairs xs ys = do
x <- xs
y <- ys
return (x, y)Utilisation :
result = pairs [1,2] [3,4] -- [(1,3),(1,4),(2,3),(2,4)]Explication : Chaque combinaison est générée automatiquement. La monade liste enchaîne les calculs pour chaque élément.
main :: IO ()
main = do
putStrLn "Entrez votre nom :"
name <- getLine
putStrLn ("Bonjour, " ++ name ++ " !")Explication :
IO est un contexte qui modélise les effets de bord. L’utilisation de la notation do garantit que les actions sont effectuées dans l’ordre.
Voyons ce que ces exemples ont en commun :
-
Ils enveloppent (« taguent ») une valeur :
-
Maybe asignifie « un a, ou rien ». -
[a]signifie « zéro ou plusieurs a ». -
IO asignifie « un a, produit par une action ».
-
-
Ils offrent un moyen de chaîner les calculs :
- Si vous avez une fonction qui produit une valeur dans le contexte, vous pouvez utiliser
>>=pour enchaîner d'autres étapes, en respectant toujours le contexte.
- Si vous avez une fonction qui produit une valeur dans le contexte, vous pouvez utiliser
sqrtMaybe :: Double -> Maybe Double
sqrtMaybe x
| x < 0 = Nothing
| otherwise = Just (sqrt x)
pipeline = do
a <- safeDiv 10 2 -- Just 5
b <- sqrtMaybe a -- Just 2.236...
return b
-- pipeline == Just 2.236...numbers = [1,2]
adders = [10,100]
result = numbers >>= (\n -> adders >>= (\a -> return (n + a)))
-- [11,101,12,102]main :: IO ()
main = getLine >>= (\name -> putStrLn ("Salut, " ++ name ++ " !"))class Applicative m => Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a-
>>=est « bind » : prend une valeur dans un contexte (m a) et une fonction qui prend une valeur normale et retourne une valeur dans le même contexte (a -> m b). -
returnélève une valeur simple dans le contexte.
-
Identité à gauche :
return a >>= f≡f a(Mettre une valeur dans le contexte et l’enchaîner équivaut à juste appliquer la fonction.) -
Identité à droite :
m >>= return≡m(Enchaîner avecreturnne change pas le résultat.) -
Associativité :
(m >>= f) >>= g≡m >>= (\x -> f x >>= g)(La façon de regrouper les calculs n’affecte pas le résultat.)
f x = Just (x + 1)
m = Just 2
-- Identité à gauche
return 2 >>= f -- Just 3
f 2 -- Just 3
-- Identité à droite
m >>= return -- Just 2
m -- Just 2
-- Associativité
((m >>= f) >>= f) == (m >>= (\x -> f x >>= f))g x = [x, x*2]
-- Identité à gauche
return 3 >>= g -- [3,6]
g 3 -- [3,6]main = do
putStrLn "Entrez :"
n <- readLn
print (n * 2)(Vous pouvez imaginer que la lecture et l’impression doivent respecter ces lois pour composer proprement.)
La notation do est un sucre syntaxique pour enchaîner des opérations monadiques.
pipeline = do
a <- Just 3
b <- Just 4
return (a + b)
-- Just 7Équivalent à :
Just 3 >>= (\a ->
Just 4 >>= (\b ->
return (a + b)))pairs = do
x <- [1,2]
y <- [10,20]
return (x, y)
-- [(1,10),(1,20),(2,10),(2,20)]main = do
putStrLn "Quel est votre nom ?"
name <- getLine
putStrLn ("Bonjour, " ++ name)Bernard Sibanda is a global Technology Entrepreneur, Web3 and Software Consultant with a deep focus on Cardano Blockchain, Midnight and Community building.
Key Positions:
- Founder, CTO, Developer Advocate cohort #1, Fullstake Developer, Cardano Ambassador, Catalyst Project Manager, DREP-WIMS:
- Co-founder of ABL Tech and Cardano Africa Live
- EBU-certified Plutus Pioneer (Plutus/Haskell)
- Cohort #1 Plutus Pioneer Developer
- Catalyst Community Reviewer & Funded Projects Manager
-
DRep for WIMS-Cardano (ID:
drep1yguj8zu48n99pv70yl6ckzt9hdgjy8yjnlqs2uyzcpafnjgu4vkul) - Intersect Developer Advocate
- Intersect Committe Member 2025-2026
- Cardano Marketer,Promoter and blogger
- Cardano Open Source Contributor
- Cardano communities and events organizer and builder
- Cardano Ambassador for South Africa
Official links:
- Stablecoins Dex
- Coxygen Global Universities
- WIMS Cardano Global
- Cardano Africa Live
- WIMS Cardano Videos
- Cardano Smart Contract Videos
- Fullstack IT Consulting
Social links: