Yatima2975 semble avoir couvert vos deux premières questions, je vais essayer de couvrir la troisième. Pour ce faire, je traiterai un cas d'une simplicité irréaliste, mais je suis sûr que vous pourrez imaginer quelque chose de plus réaliste.
Imaginez que vous vouliez calculer la profondeur de l' arbre binaire complet d'ordre . Le type d'arbres binaires (sans étiquette) est (dans la syntaxe Haskell):n
type Tree = Leaf | Node Tree Tree
Maintenant, l'arbre complet d'ordre est:n
full : Int -> Tree
full n | n == 0 = Leaf
full n = Node (full (n-1)) (full (n-1))
Et la profondeur d'un arbre est calculée par
depth : Tree -> Int
depth Leaf = 0
depth (Node t1 t2) = 1 + max (depth t1) (depth t2)
Vous pouvez maintenant voir que tout calcul de va d'abord construire l'arborescence complète d'ordredepth (full n)nfulld e p t hdepth (full n)full_depth
full_depth : Int -> Int
full_depth n | n == 0 = 0
full_depth n = 1 + max (full_depth (n-1)) (full_depth (n-1))
Cela évite l'allocation de mémoire de l'arborescence complète et la nécessité d'effectuer une correspondance de modèle, ce qui améliore considérablement les performances. De plus, si vous ajoutez l'optimisation
max t t --> t
full_depth
Le seul compilateur grand public qui effectue la déforestation automatique est GHC, et si je me souviens bien, cela n'est effectué que lors de la composition de fonctions intégrées (pour des raisons techniques).
Tout d'abord, les listes sont une sorte d'arbres. Si nous représentons une liste sous forme de liste liée , il s'agit simplement d'un arbre dont chaque nœud a 1 ou 0 descendants.
Les arbres d'analyse ne sont qu'une utilisation des arbres comme structure de données. Les arbres ont de nombreuses applications en informatique, notamment le tri, la mise en œuvre de cartes, les tableaux associatifs, etc.
En général, la liste, les arbres, etc. sont des structures de données récursives: chaque nœud contient des informations et une autre instance de la même structure de données. Le pliage est une opération sur toutes ces structures qui transforme récursivement les nœuds en valeurs "ascendantes". Le dépliage est le processus inverse, il convertit les valeurs en nœuds "de haut en bas".
Pour une structure de données donnée, on peut construire mécaniquement leurs fonctions de pliage et de dépliage.
Par exemple, prenons des listes. (Je vais utiliser Haskell pour les exemples car il est tapé et sa syntaxe est très propre.) La liste est soit une fin, soit une valeur et une "queue".
Imaginons maintenant que nous plions une liste. À chaque étape, nous avons le nœud actuel à plier et nous avons déjà plié ses sous-nœuds récursifs. Nous pouvons représenter cet état comme
où
r
est la valeur intermédiaire construite en repliant la sous-liste. Cela nous permet d'exprimer une fonction de pliage sur des listes:Nous convertissons
List
enListF
repliant récursivement sa sous-liste, puis utilisons une fonction définie surListF
. Si vous y réfléchissez, ce n'est qu'une autre représentation de la normefoldr
:On peut construire
unfoldList
de la même manière:Encore une fois, c'est juste une autre représentation de
unfoldr
:(Notez que
Maybe (a, r)
c'est isomorphe àListF a r
.)Et nous pouvons aussi construire une fonction de déforestation:
Il supprime simplement l'intermédiaire
List
et fusionne les fonctions de pliage et de dépliage.La même procédure peut être appliquée à toute structure de données récursive. Par exemple, un arbre dont les nœuds peuvent avoir 0, 1, 2 ou descendants avec des valeurs sur des nœuds à 1 ou 0 branches:
Bien sûr, nous pouvons créer
deforestTree
aussi mécaniquement qu'auparavant.(Habituellement, nous exprimons
treeFold
plus facilement:)
Je vais laisser de côté les détails, j'espère que le motif est évident.
Voir également:
la source
C'est un peu déroutant, mais la déforestation est appliquée (au moment de la compilation) pour éliminer les arbres intermédiaires qui seraient créés (au moment de l'exécution). La déforestation n'implique pas de pirater des parties de l'arbre de syntaxe abstraite (c'est l'élimination des branches mortes :-)
Une autre chose qui vous a peut-être dérouté est que les listes sont des arbres, juste des arbres très déséquilibrés!
la source