Nous continuons notre exploration des Monades/Functors, nous allons parler de Collection, de lapins, de marteaux et de non-déterminisme.
Voici notre nouveau container Le container List. Il prend en entrée un tableau (Array) ou en Php un Traversable
.
Nous allons voir ensemble les listes, Collections. Nous allons voir le map
, le bind
nous allons voir que le comportement n’est pas exactement le même..
Ne nous embêtons pas allons directement dans l’implémentation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
On garde toujours la même définition. map
prend toujours une fonction et renvoie un Objet du même type. extract
renvoie la valeur, Collection::of
renvoie une collection.
Quelques exemples
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Nous allons reprendre notre liste du post précédent
1 2 3 4 5 |
|
- Nous allons transformer chaque ligne en
maybe
grâce à l’instructionmaybeFromValue
(post2)
Nous aimerions utiliser notre instruction get
.
l’algo :
- je récupère le maybe.
- J’appelle la fonction bind du maybe avec le get
Cela donne ..
1 2 3 4 5 6 7 8 |
|
Oui vous ne rêvez pas c’est une fonction qui renvoie une fonction qui renvoie une fonction.
L’implémentation est sympathique..
1 2 3 4 5 6 |
|
Nous obtenons en une ligne sans if sans condition.
1
|
|
Le bind
Je n’ai pas donnée le code du bind qui se résume à
1 2 3 4 |
|
Je vais essayer de justifier tout cela.
Partons d’abord du principe que $this->concat
n’existe pas..
Donc mon bind
devient
1 2 3 4 |
|
Un exemple
1 2 3 4 5 6 7 |
|
Le résultat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Nous avons une collection qui contient une collection (double container!!) et pire dans chaque valeur est encore une collection !. On perd aussi le chainage.
Bref nous avons tout perdu.
Solution le marteau.
Nous allons aplatir le résultat.
C’est a dire que nous allons transformer notre collection [[a],[b],[c]]
en [a, b, c]
Voici l’implémentation en code.. C’est un peu long n’hésitez pas à sauter cette partie..
Partons du principe que c’est un array..
On aplati notre liste ainsi
1 2 3 4 5 6 7 8 |
|
Le problème est que notre collection n’est pas un Array
.. Mais essayons avec une fonction un peu plus tordue
1 2 3 4 5 6 7 8 |
|
C’est un façon un peu plus complexe d’exprimer la même chose que le code plus haut. Sans utiliser les boucles foreach
.
Le reduce pour notre collection est facilement exprimable.
1 2 3 4 5 6 7 8 9 |
|
Reprenons le code du array_reduce
et utilisons notre reduce
1 2 3 4 5 6 7 8 9 10 11 |
|
Voici comment on aplatit notre fonction et on sauvegarde le chainage. Mais il y a mieux..
Si j’avais un marteau..
Montrons quelque exemples de bind.
Exemple 1 : Les lapins.
Soit le fonction suivante
1 2 3 |
|
Un exemple
1 2 3 4 |
|
Le résultat
- premier bind
1
|
|
- second bind
1
|
|
Nous commençons avec un lapin, nous multiplions par 3 à chaque interaction. Comme la liste est aplatie à chaque fois.
Exemple 2 : les fractales
Soit la fonction suivante
1 2 3 4 5 6 7 8 |
|
Exemple 3 : avec les chiffres
Soit la fonction suivante
La fonction inférieure à 20 renvoie un array vide.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
- premier
bind
1
|
|
- second
bind
1
|
|
- troisième
bind
1
|
|
Exemple 4: Trouver les positions possibles d’un jeux de société
1 2 3 4 5 6 7 |
|
cette fonction donne toute les parties possibles dans deux coup.
Conclusion
On comprend assez bien l’intérêt de cette monade pour gérer des listes, mais il y a une autre vision possible. La collection avec le bind est considérée comme une façon de gérer des entrées non déterministes. J’ai eu un peu de mal à comprendre, mais voici l’idée.
La valeur 3 n’a qu’une valeur qui est 3
facile, la valeur [1, 2, 3]
est une représentation de la même valeur sauf qu’elle à trois états possible 1, 2, 3
. Grâce au bind
je prend en compte tous les états possibles.
Pour résumer :
- Le Maybe prend le cas ou la valeur est présente.
- La liste permet de gérer le Non-determinisme.
Il reste encore beaucoup de chose à parler. Nous avons parlé des functors(map
ou fmap
), des monades (of
et bind
) nous allons voir les applicatives..
des liens.
- Ma référence pour l’implémentation est php-functional.
- La bible pour le haskell est Learn You a Haskell for Great Good! Le livre est gratuit avec des jolis dessins. Enfin le fond et la forme sont vraiment bon.
Il existe en français !! Apprendre Haskell vous fera le plus grand bien !
Partie 1 : Monade/Functor
- Partie 2 : Le functor Maybe
- Partie 3 : Le functor Maybe avec le Bind
- Partie 4 : Les listes
- Interlude : Les évaluations partielles
- Partie 5 : Les applicatives