Comme le M dans son nom l'indique, replicateM travaille dans une monade. La première chose à faire est donc de déterminer dans quel monade "replicateM 4 ['0','1']" travaille (j'ai réécris "01" en ['0','1'] pour que la suite soit plus claire).
Le type de replicateM est :
replicateM :: (Monad m) => Int -> m a -> m [a]
Donc "replicateM 4 ['0','1']" travaille dans la monade [] (Liste), comme le type de son second argument l'indique. La monade liste peut être vue comme "non-déterministe", chaque valeur dans la monade liste peut être vue comme une superposition de valeur possible, et une action de la monade liste renvoie la liste des valeurs résultats possibles, un exemple simple est :
1 2 3 4
| superProduit xs ys = do
x <- xs
y <- ys
return (x*y) |
superProduit [2,3] [4,5] renvoie [8,10,12,15], la liste des produits possibles entre des éléments de la première et la deuxième liste.
La monade liste est également celle qui sert pour les compréhension de listes.
Ce que fait replicateM est relativement simple : "replicateM n a" est une action monadique qui répète n fois l'action a et renvoie la liste des résultats.
Un exemple simple d'utilisation est :
1 2 3 4
| main = do
putStrLn "Entrez trois nombres (pressez Entrée après chaque) :"
ns <- replicateM 3 readLn
print (sum ns) |
Dans ce cas, on travaille dans la monade IO.
Revenons à "replicateM 4 ['0','1']", on voit donc que cette action "choisit" 4 fois entre 0 ou 1 et nous renvoie la liste des résultat, pour chaque combinaison de 4 choix possibles. Autrement dit, elle nous renvoie l'ensemble des chaînes de 4 caractères parmi 0 ou 1.
On pourrait aussi l'écrire :
[[w,x,y,z] | w <- "01", x <- "01", y <- "01", z w <- "01"]
NB : Il est facile d'écrire replicateM soi-même, soit par une récursion explicite (et laide) :
1 2 3
| replicateM n a
| n > 0 = do x <- a; xs <- replicateM (n-1) a; return (x:xs)
| otherwise = return [] |
soit plus élégamment avec le séquenceur monadique de base (sequence) et la fonction replicate sur les listes :
replicateM n a = sequence (replicate n a)
--
Jedaï
Partager