On se propose de créer un mécanisme pour faire des boucles façon while ou for tout en restant pûrement fonctionnel : sans assignation.
Pour cela nous proposons la fonction suivante :
Voici l'interface d'une monade d'état :
Il faut comprendre que 'value t est une action produisant une valeur de type 'value. Par ailleurs, cette action a accès à un état qu'elle peut lire ou écrire.
On suppose disposer d'une monade d'état dont le type stateest int.
Écrivez l'action permettant de calculer la factorielle d'un entier $n$ à l'aide de la question précédente. Vous pouvez modifier l'état arbitrairement.
Divers langages de programmation proposent des générateurs, permettant d'énumérer des valeurs en les générant une par une, en se basant sur un mot-clé tel que yield. Un yield ressemble à un return sauf que l'appelant peut ensuite revenir dans la fonction au point juste après le yield. On utilise ensuite une boucle pour traiter toutes las valeurs ainsi générable. Par exemple, on peut écrire en Python :
Cela permet notamment de définir facilement des itérables (comparativement à Java par exemple, essayez de définir un itéreur de nœud d'un arbre par exemple).
La façon naturelle de faire en OCaml est d'utiliser une liste paresseuse. Voici une autre méthode. On définit le module :
Voici la version OCaml du code Python :
Écrivez un itérateur des éléments d'une liste :
Écrivez un itérateur des nœuds d'un arbre binaire :
Cette version permet à l'utilisateur de l'itérateur de retourner des valeurs au générateur : la communication se passe dans les deux sens. On peut en profiter, par exemple pour faire un algorithme de recherche d'une clé dans un arbre binaire de recherche. Créez les deux fonctions suivantes :
find_key retourne le sous-arbre ayant l'élément cherché pour racine, ou une feuille.