Nous avons mentionné que les listes sont un type inductif, certes avec des constructeurs un peu particulier : ils ne respectent pas les conventions d'être des identifiants commençant par une majuscule, et :: s'utilise en position infixe.
Pour le reste, il s'agit en tout point d'un type inductif, et on peut donc les manipuler avec des algorithmes inductifs. De fait, c'est ainsi que sont définies les fonctionnelles de listes vues au cours précédent.
Essayons d'écrire directement, par un algorithme inductif, la fonction testant que tous les entiers d'une liste sont pairs :
Pour obtenir la fonction for_all, il suffit de remarquer que la seule chose spécifique au test de parité est l'appel is_even head dans le deuxième cas. En remplaçant is_even par une condition arbitraire, prise en argument, on obtient :
Il faut bien sûr redonner l'argument supplémentaire lors de l'appel récursif. Toutes les fonctionnelles de listes s'obtiennent de cette façon : à partir de schémas d'induction sur les listes, on généralise les actions qui ne sont pas directement liées à la manipulation des listes, en les abstrayant comme des fonctions prises en argument. Dérivons fold_right de cette manière.
À la base, nous pouvons partir de la fonction sommant les éléments d'une liste. En OCaml par induction on obtient :
Les seules termes qui sont propres au calcul de la somme, et non à la récursion, c'est le 0 de la ligne 2 , et le + de la ligne 3 . On les abstrait,et on obtient fold_right :
fold_left est moins naturel, pour le comprendre il est plus simple de commencer par la version Java :
Ici, la valeur d'initialisation, ainsi que la somme à chaque itération, peuvent être abstraites. La valeur d'initialisation est abstraite par initValue, qui peut avoir un type arbitraire. La somme est abstraite par une fonction combine.
La fonctionnelle fold_left d'OCaml peut être comprise comme une version inductive de cette boucle. Écrivons l'induction pour la somme d'une liste. Ce qui change est qu'on doit commencer par la somme de la valeur initiale, et du premier élément de la liste. Il faut donc une valeur initiale en argument de la fonction. Notons que le résultat de l'addition devient la valeur de la variable locale sumen Java. Pour l'induction, c'est l'argument de valeur initiale qui remplit le rôle de sum.
Il suffit maintenant d'abstraire la fonction appliquée à la valeur initial et la tête.
Le même travail peut être effectué sur chacune des fonctionnelles. Cependant, ce n'est pas nécessaire : l'intérêt des fonctionnelles est justement de ne pas avoir à réécrire systématiquement des fonctions bas-niveaux inductives.
Néanmoins, il est parfois intéressant d'utiliser des inductions pour certaines manipulations de listes. Les fonctionnelles capturent la plupart des schémas d'induction courants pour les listes, mais pas tous. Il faut donc être capable de repérer avec aisance les cas d'application des fonctionnelles de listes, et lorsque les fonctionnelles de listes sont inadaptés, revenir sur une induction, puis se demander si l'induction n'est pas généralisable en une fonctionnelle naturelle qui pourrait être réutilisée.