IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Func' programming - un blog homéopathique

[Actualité] Origami

Noter ce billet
par , 31/03/2015 à 12h06 (1538 Affichages)
L’imagination au pouvoir
L’Origami, art du pliage, permet de transformer une simple feuille en une grue, un canard ou un brontosaure –art poétique, donc, qui fait émerger de la virginité d’une page un monstre depuis longtemps disparu ou le vol d’un oiseau. Peut-être que notre activité –à nous autres programmeurs- n’a pas pour le grand public l’attrait oriental de cette discipline épurée et pourtant ! ne consiste-t-elle pas à faire émerger du chaos d’interminables séquences de bits des structures vivantes et disciplinées ?

L’art du pliage
C’est dans cet état d’esprit que je voudrais aujourd’hui illustrer l’art du pliage… des listes. Nous répèterons les gestes constitutifs de cet art comme autant de katas pour en percevoir l’extrême versatilité.

Il existe essentiellement deux formes de pliage : de gauche à droite, et de droite à gauche. De gauche à droite, on pose d’abord un pan du tissu sur la table, puis on ramène le tissu, pli par pli. De droite à gauche, on tient le tissu à la main et on l’attire vers soi, pour ne le déposer qu’à la fin sur la table. Pour plier une liste, également, on suit un ordre ou l’autre : il nous faut une fonction qui décrive le pli, une valeur initiale qui tient lieu de table et une liste, enfin, notre tissu. En voici la transcription en code

N.B : pour les rudiments de Haskell nécessaires à la lecture de ce billet, voir le précédent.

Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
-- foldl : fold en anglais, plier en français ; l pour left : de gauche à droite
foldl _ i [] = i      --il n’y a plus de morceau à plier, on donne la liste pliée
foldl f i (x:xs) = foldl f (f i x) xs    --on replie sur la valeur initiale le prochain pan de la liste
 
-- foldr : fold right, de droite à gauche
foldr _ i [] = i    -- arrivés au bout de la liste, nous la posons sur la table
foldr f i (x:xs) = f x (foldr f i xs)     --nous plions le premier morceau de la liste sur le reste de la liste à plier

Quelques figures simples
Regardons un peu ce que l’on peut faire avec ces deux gestes simples et des fonctions primitives :

copy = foldr ( : ) [] --le constructeur de liste, qui est un opérateur, est placé entre parenthèse pour être utilisé comme une fonction
length = foldr (\x y -> 1+y) 0 --longueur de la liste
remove elem = foldr (\x y -> if x == elem then y else x:y) [] --retirer un élément de la liste
sum = foldr (+) 0 --somme
product = foldr (*) 1 --produit
append a b = foldr ( : ) b a --concaténer deux listes
map f = foldr (( : ) . f) [] --appliquer une fonction à une liste

La direction du pli ne compte pas toujours, mais souvent: Prenez par exemple ce joli bout de code :

N.B : flip intervertit l’ordre des arguments d’une fonction : flip f = \x y -> f y x

reverse = foldl (flip ( : )) [] --inverse l’ordre de la liste

Une figure pour le poker
Je vous avais promis une formulation plus élégante de split-if, utilisée pour analyser les mains au poker (fonction développée et utilisée lors des trois précédents billets), la voici, d’un geste de Samouraï :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
--@ permet de nommer la structure déconstruite par pattern matching
splitIf' p xs = foldr (ft p) [[]] xs
where ft _ x [[]] = [[x]] ;
ft p x n@((y:ys):zs) = if p x y then [x] : n else (x:y:ys) : zs
En voici une de disambiguate :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
disambiguate' a b = foldr (\x y -> if x == EQ then y else x) EQ $ zipWith compare a b       
--les recherches sur compare et zipWith sont laissées au lecteur
Plier son cerveau
Enfin je propose, à ceux qui n’auraient dans la journée que la stimulation intellectuelle de faire des boucles,

Code : Sélectionner tout - Visualiser dans une fenêtre à part
for (int i = 0 ; i < MAX_VAL ; ++i)  // si j’avais gagné un euro à chaque fois…
un petit bout de code qui leur tordra convenablement le cerveau :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
foldl f a bs =   foldr (\b g x -> g (f x b)) id bs a
Pour ceux qui doutent encore…
de l’intérêt de tout cela, j’annonce une série de billets prochains sur la mise en place d’une IA simple et modulaire pour des jeux de plateau mettant à profit les katas du jour. Nous rendrons ainsi hommage aux morpions !
Comme il se peut que j’aie quelques notions importantes à présenter d’abord, laissez-moi tout de même un ou deux billets avant de lancer la série.

Exercices :
- réfléchir aux représentations d’un plateau de morpions
- faites une recherche sur l’algorithme minimax
- êtes-vous plutôt strict ou paresseux ? si vous êtes plutôt paresseux, je montrerai dans le prochain billet tous les bénéfices de ce trait de caractère…

Envoyer le billet « Origami » dans le blog Viadeo Envoyer le billet « Origami » dans le blog Twitter Envoyer le billet « Origami » dans le blog Google Envoyer le billet « Origami » dans le blog Facebook Envoyer le billet « Origami » dans le blog Digg Envoyer le billet « Origami » dans le blog Delicious Envoyer le billet « Origami » dans le blog MySpace Envoyer le billet « Origami » dans le blog Yahoo

Mis à jour 31/03/2015 à 13h50 par stendhal666

Catégories
Programmation

Commentaires

  1. Avatar de vasilpapa
    • |
    • permalink
    Enfin un tuto différent ! La on apprends. Si vous pourriez compléter par des exemples qui nous montrerait le resultat et dans quel cas concret on utilise telle ou telle function, personnellement je serais comblé.
    Merci d'user de votre temps pour nous les novices. Il n'y a que comme ca qu'on peut rendre Haskell plus populaire.
  2. Avatar de stendhal666
    • |
    • permalink
    Merci pour ce très aimable commentaire!

    Je ne sais pas trop ce que tu entends par "quel cas concret"? Un livre très bien fait pour avoir des exemples Haskell proches du "monde réel" est le livre Real world Haskell (http://book.realworldhaskell.org/read/) disponible gratuitement mais en anglais.

    Pour ma part, dans des billets de blog, je suis un peu limité par la place, mais j'espère donner des exemples plus développés à l'avenir, quand les techniques de base seront couvertes. Pour l'instant, c'est à dose homéopathique...