3. L'Opérateur Pipe |>
🎯 Le Problème
Code difficile à lire
Problème : On doit lire de l'intérieur vers l'extérieur !
Mais le code s'écrit dans l'ordre inverse de la lecture ! 😵
💡 La Solution : L'Opérateur |>
Syntaxe
Se lit : "Prends valeur et applique-lui fonction"
Exemple Simple
Les deux sont équivalents !
📖 Lire de Gauche à Droite
Chaîner des Opérations
-- ❌ Sans pipe : lecture compliquée
resultat = taille (renverse (pairs [1, 2, 3, 4, 5]))
-- ✅ Avec pipe : lecture naturelle
resultat =
[1, 2, 3, 4, 5]
|> pairs -- [2, 4]
|> renverse -- [4, 2]
|> taille -- 2
Ordre de lecture = ordre d'exécution ! 🎯
Visualisation
🔧 Comment Ça Marche ?
Définition de |>
Traduction :
- Prends une valeur de type
a - Prends une fonction qui accepte
aet retourneb - Applique la fonction à la valeur
- Retourne le résultat de type
b
Transformation
-- Ceci
x |> f
-- Est transformé en cela
f x
-- Donc
[1, 2, 3] |> taille
-- Devient
taille [1, 2, 3]
📝 Exemples Pratiques
Exemple 1 : Traitement de Liste
-- Calculer la somme des nombres pairs
resultat =
[1, 2, 3, 4, 5, 6]
|> pairs -- [2, 4, 6]
|> somme -- 12
-- Équivalent sans pipe
resultat = somme (pairs [1, 2, 3, 4, 5, 6])
Exemple 2 : Avec des Fonctions à Plusieurs Paramètres
-- take : Int -> Liste a -> Liste a
-- On peut l'utiliser avec |> !
[1, 2, 3, 4, 5]
|> take 3 -- [1, 2, 3]
|> somme -- 6
-- Équivalent
somme (take 3 [1, 2, 3, 4, 5])
Astuce : La valeur avant |> devient le dernier paramètre de la fonction.
Exemple 3 : Pipeline Complexe
traiterDonnees : Liste Int -> Int
traiterDonnees lst =
lst
|> pairs -- Garde les pairs
|> take 3 -- Prends les 3 premiers
|> dupliquer -- Duplique chaque élément
|> somme -- Additionne tout
traiterDonnees [1, 2, 3, 4, 5, 6, 7, 8]
--> (2 + 2 + 4 + 4 + 6 + 6) = 24
Exemple 4 : Avec des Lambdas
[1, 2, 3, 4, 5]
|> (\lst -> take 2 lst) -- Lambda qui prend 2 éléments
|> somme -- 3
-- Ou plus simple avec application partielle
[1, 2, 3, 4, 5]
|> take 2
|> somme
🎨 Style et Lisibilité
Quand Utiliser le Pipe ?
✅ Oui : Plusieurs Transformations
✅ Oui : Opérations Séquentielles
❌ Non : Une Seule Fonction
❌ Non : Fonction Avec Plusieurs Arguments
🔄 Indentation et Format
Style Recommandé
Avec Commentaires
traiterCommande : Liste Int -> Int
traiterCommande commande =
commande
|> pairs -- Filtrer les quantités paires
|> take 10 -- Maximum 10 articles
|> somme -- Total de la commande
|> (\x -> x * 2) -- Doubler pour promotion
Longues Lignes
-- Si les fonctions sont longues, indente plus
resultat =
maDonnee
|> fonctionAvecUnNomTresLong
|> autreFonctionCompliquee
|> encoreUneFonction
⚡ Cas Pratiques dans Tes Exercices
Exemple 1 : renverse avec ajouterFin
-- Version compliquée à lire
renverse : Liste a -> Liste a
renverse lst =
case lst of
Vide -> Vide
Cons tete queue -> ajouterFin tete (renverse queue)
-- Avec pipe (plus clair dans certains contextes)
-- Note: ici le pipe n'aide pas vraiment,
-- c'est juste pour montrer qu'on peut l'utiliser
Exemple 2 : Tester des Fonctions
-- Au lieu de
test1 = taille (renverse (pairs lstEx1))
-- Avec pipe
test1 =
lstEx1
|> pairs
|> renverse
|> taille
-- Beaucoup plus clair ce qu'on teste !
Exemple 3 : range avec take
-- Créer [0, 1, 2, 3, 4]
cinqPremiers : Liste Int
cinqPremiers =
range 10 -- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|> take 5 -- [0, 1, 2, 3, 4]
Exemple 4 : Combiner avec concat
-- Concaténer puis traiter
combineEtTraite : Liste Int -> Liste Int -> Int
combineEtTraite lst1 lst2 =
concat lst1 lst2 -- Combine les listes
|> pairs -- Garde les pairs
|> somme -- Additionne
-- Utilisation
combineEtTraite [1, 2, 3] [4, 5, 6]
--> (2 + 4 + 6) = 12
🤔 Questions Fréquentes
Q1 : Puis-je mélanger parenthèses et pipes ?
Oui !
resultat =
(take 3 [1, 2, 3, 4, 5])
|> somme
|> (\x -> x * 2)
-- Ou
resultat =
[1, 2, 3, 4, 5]
|> take 3
|> somme
|> (\x -> x * 2)
Q2 : Comment avec des fonctions à 2+ paramètres ?
Application partielle !
-- concat : Liste a -> Liste a -> Liste a
-- On donne le premier argument, pas le deuxième
[1, 2, 3]
|> concat [4, 5, 6] -- concat [1,2,3] [4,5,6]
|> taille -- 6
-- La valeur avant |> devient le DERNIER argument
Q3 : Peut-on utiliser |> avec nos propres fonctions ?
Oui, avec n'importe quelle fonction !
maFonction : Int -> Int
maFonction x = x * 2 + 1
5 |> maFonction
--> 11
-- Même avec des fonctions complexes
monTraitement : Liste Int -> Bool
monTraitement lst = taille lst > 5
[1, 2, 3, 4, 5, 6] |> monTraitement
--> True
Q4 : Quelle est la limite ?
Aucune ! Tu peux chaîner autant que tu veux
resultat =
[1, 2, 3, 4, 5]
|> fonction1
|> fonction2
|> fonction3
|> fonction4
|> fonction5
|> fonction6
-- etc...
🎓 Exercices de Compréhension
Transforme ces expressions avec |> :
Exercice 1
Exercice 2
-- Sans pipe
somme (pairs (take 5 [1, 2, 3, 4, 5, 6]))
-- Avec pipe
[1, 2, 3, 4, 5, 6]
|> take 5
|> pairs
|> somme
Exercice 3
-- Sans pipe
taille (concat [1, 2] [3, 4, 5])
-- Avec pipe
[1, 2]
|> concat [3, 4, 5]
|> taille
-- Résultat : 5
🚀 Comparaison avec d'Autres Langages
JavaScript (méthodes chaînées)
// JavaScript
[1, 2, 3, 4, 5]
.filter(x => x % 2 === 0)
.map(x => x * 2)
.reduce((a, b) => a + b, 0)
Elm (avec pipe)
Même principe, syntaxe différente !
Unix (pipes en ligne de commande)
Elm
✅ Résumé : Pourquoi Utiliser |> ?
Avantages
- Lisibilité : Ordre naturel gauche → droite
- Clarté : Chaque transformation est explicite
- Débogage : Facile de commenter/décommenter une étape
- Style : Code Elm idiomatique
Le Pattern
Se lit comme une recette de cuisine ! 👨🍳
🎯 Conseil Final
Utilise |> quand tu as 2+ transformations séquentielles.
-- ✅ Bon usage
resultat =
maListe
|> pairs
|> somme
-- ❌ Pas nécessaire
resultat = maListe |> taille
-- ✅ Mieux
resultat = taille maListe
Le pipe est ton ami pour écrire du code clair et lisible ! 🚀
📚 Pour Aller Plus Loin
Une fois que tu maîtrises |>, tu peux découvrir :
- <| (pipe inversé, moins courant)
- >> (composition de fonctions)
- << (composition inversée)
Mais pour l'instant, |> suffit largement ! 💪