Oh, ce n'est pas vraiment spécifique à Haskell ça. En fait, tu as un type récursif :
dataTreea=Node[(a,Treea)]
Or traiter un type récursif c'est pas toujours facile. Du coup tu généralise, en regardant son homologue non récursif :
dataTree'ab=Node'[(a,b)]
On remarque que le deuxième est un type « normal », c'est à dire non récursif. Tu peux ensuite (formellement) écrire
Treea<=>Tree'a(Treea)
Car on remplace b par Tree a et on a des structures identiques (au nom du constructeur près).
Pour simplifier, on peut prendre le type liste :
dataListea=Consa(Listea)|Vide
Sa contrepartie non-récursive est
dataPaireab=Cons'ab|Vide
Et on remarque bien que : Liste a <=> Paire a (Liste a).
Mieux tu peux définir le type récursif comme étant le type T a tel que Paire a (T a) = T a. Ce qui se comprend comme : une liste c'est un type tel que si je le met dans une paire, c'est encore une liste.
Quel intérêt ? Et bien, cela donne automatiquement une manière de « faire pousser » la structure. Pour nous c'était un arbre, pour la liste c'est pareil, il existe une fonction unfold qui permet de le faire.
Par exemple, on déduit la signature de unfold pour les listes :
Paireab=Cons'ab|VideListea<=>Fixe(Pairea)unfoldFinal::b->Listea-- Ce que l'on veut f::(b->Paireab)-- Ce que l'on sait faire unfold::(b->Paireab)->b->Listea
Mieux, tu as aussi l'inverse (ie : partir d'une liste et arriver à une valeur).
foldFinal::Listea->b-- Ce que l'on veut f::Paireab->b-- Ce que l'on sait faire fold::(Paireab->b)->Listea->b-- Exemple d'utilisation quand a = b = Nombre somme::[Nombre]->Nombre-- Ce que l'on veut add::PaireNombreNombre->Nombre-- Ce que l'on sait faire addVide=0add(Cons'xy)=x+ysommeliste=foldaddlist
Il faudrait que je retrouve un article qui en parlait de manière plus générale. En tout cas la page wikipédia anglaise est assez bien faite.
[^] # Re: Intéressant, mais Haskell
Posté par Aluminium95 . En réponse au journal Résolution naïve d'un jeu de société. Évalué à 2.
Oh, ce n'est pas vraiment spécifique à Haskell ça. En fait, tu as un type récursif :
Or traiter un type récursif c'est pas toujours facile. Du coup tu généralise, en regardant son homologue non récursif :
On remarque que le deuxième est un type « normal », c'est à dire non récursif. Tu peux ensuite (formellement) écrire
Car on remplace
bparTree aet on a des structures identiques (au nom du constructeur près).Pour simplifier, on peut prendre le type liste :
Sa contrepartie non-récursive est
Et on remarque bien que :
Liste a <=> Paire a (Liste a).Mieux tu peux définir le type récursif comme étant le type
T atel quePaire a (T a) = T a. Ce qui se comprend comme : une liste c'est un type tel que si je le met dans une paire, c'est encore une liste.Quel intérêt ? Et bien, cela donne automatiquement une manière de « faire pousser » la structure. Pour nous c'était un arbre, pour la liste c'est pareil, il existe une fonction
unfoldqui permet de le faire.Par exemple, on déduit la signature de
unfoldpour les listes :Mieux, tu as aussi l'inverse (ie : partir d'une liste et arriver à une valeur).
Il faudrait que je retrouve un article qui en parlait de manière plus générale. En tout cas la page wikipédia anglaise est assez bien faite.