Je suis curieux de la performance d'exécution d'une liste infinie comme celle ci-dessous :
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
Cela créera une liste infinie de la séquence de Fibonacci.
Ma question est que si je fais ce qui suit :
takeWhile (<5) fibs
combien de fois évalue fibs
chaque terme dans la liste ? Il semble que puisque takeWhile
vérifie la fonction prédicat pour chaque élément dans la liste, la liste fibs
évaluera chaque terme plusieurs fois. Les deux premiers termes sont donnés gratuitement. Lorsque takeWhile
veut évaluer (<5)
sur le 3ème élément, nous aurons :
1 : 1 : zipWith (+) [(1, 1), (1)] => 1 : 1 : 3
Maintenant, une fois que takeWhile
veut évaluer (<5)
sur le 4ème élément : la nature récursive de fibs
reconstruira la liste à nouveau comme suivant :
1 : 1 : zipWith (+) [(1, 2), (2, 3)] => 1 : 1 : 3 : 5
Il semblerait que le 3ème élément doit être calculé à nouveau lorsque nous voulons évaluer la valeur du 4ème élément. De plus, si le prédicat dans takeWhile
est grand, cela indiquerait que la fonction fait plus de travail que nécessaire car elle évalue chaque élément précédent dans la liste plusieurs fois. Mon analyse est-elle correcte ici ou est-ce que Haskell fait une mise en cache pour éviter les évaluations multiples ici ?