Votre intuition sur la copie est exactement la bonne direction, vous devriez penser. Cependant, la 'copie' est implémentée intelligemment par le runtime Haskell. Par exemple, étant donné
data Tree = Empty | Branch Tree Integer Tree
Vous pouvez implémenter une fonction pour remplacer la branche gauche:
replaceLeft :: Tree -> Tree -> Tree
replaceLeft (Branch _ i r) newLeft = Branch newLeft i r
Le résultat est pas que vous créez une copie entière du nouvel arbre, comme ce n'est pas nécessaire. La valeur i
et les arbres r
et newLeft
sont inchangés, nous n'avons donc pas besoin de copier leur contenu dans une nouvelle mémoire.
Le nouveau Branch
est créé (il s'agit de la seule allocation réelle dans cet exemple: la création de la structure pour contenir les arbres gauche/droit sur le Integer
) fait toujours référence aux mêmes valeurs de l'ancienne branche, pas de copie nécessaire!
Étant donné que les structures de données sont immuables, il n'y a pas de mal à le faire.
"Ainsi, ils ne sont pas vraiment \' variables '"- Bien sûr qu'ils le sont. Par exemple, quand un mathématicien dit "Soit * G * le groupe (* S *, \ *), où ...", le * G * est une variable, même si ça ne va jamais changer. C'est le même principe chez Haskell. –
vous soulignez certainement un point intéressant, en effet la structure change un peu pour s'adapter à l'immuabilité sans sacrifier la performance. Pensez à votre structure comme un graphe orienté (où une arête de A à B signifie que A contient une référence/index à B), alors si vous souhaitez changer B, tout sommet à partir duquel B était accessible doit être copié et sa référence mise à jour . Je n'ai toujours pas trouvé comment représenter une liste de raccourcis dans Haskell par exemple :) –