Skip to content

3. L'Opérateur Pipe |>

🎯 Le Problème

Code difficile à lire

-- Calculer la taille de la liste renversée
resultat = taille (renverse (pairs [1, 2, 3, 4, 5]))

Problème : On doit lire de l'intérieur vers l'extérieur !

1. pairs [1, 2, 3, 4, 5]      --> [2, 4]
2. renverse [2, 4]            --> [4, 2]
3. taille [4, 2]              --> 2

Mais le code s'écrit dans l'ordre inverse de la lecture ! 😵


💡 La Solution : L'Opérateur |>

Syntaxe

valeur |> fonction

Se lit : "Prends valeur et applique-lui fonction"

Exemple Simple

-- Sans pipe
taille [1, 2, 3]
--> 3

-- Avec pipe
[1, 2, 3] |> taille
--> 3

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

[1, 2, 3, 4, 5]
    ↓ pairs
[2, 4]
    ↓ renverse
[4, 2]
    ↓ taille
2

🔧 Comment Ça Marche ?

Définition de |>

(|>) : a -> (a -> b) -> b
(|>) valeur fonction = fonction valeur

Traduction :

  • Prends une valeur de type a
  • Prends une fonction qui accepte a et retourne b
  • 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

-- Lisible avec pipe
resultat =
    maListe
        |> fonction1
        |> fonction2
        |> fonction3

✅ Oui : Opérations Séquentielles

-- Clair et naturel
[1, 2, 3, 4, 5]
    |> filter (\x -> x > 2)
    |> map (\x -> x * 2)
    |> somme

❌ Non : Une Seule Fonction

-- ❌ Pas nécessaire
resultat = [1, 2, 3] |> taille

-- ✅ Plus simple
resultat = taille [1, 2, 3]

❌ Non : Fonction Avec Plusieurs Arguments

-- ❌ Peu clair
resultat = 
    liste1
        |> concat liste2

-- ✅ Plus clair
resultat = concat liste1 liste2

🔄 Indentation et Format

Style Recommandé

-- Chaque étape sur une ligne
resultat =
    [1, 2, 3, 4, 5]
        |> pairs
        |> renverse
        |> taille

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

-- Sans pipe
taille (renverse [1, 2, 3])

-- Avec pipe
[1, 2, 3] |> renverse |> taille

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)

-- Elm
[1, 2, 3, 4, 5]
    |> filter (\x -> modBy 2 x == 0)
    |> map (\x -> x * 2)
    |> foldl (+) 0

Même principe, syntaxe différente !

Unix (pipes en ligne de commande)

# Bash
cat fichier.txt | grep "mot" | wc -l

Elm

-- Même concept en Elm
fichierContenu
    |> filtrerLignes "mot"
    |> compterLignes

✅ Résumé : Pourquoi Utiliser |> ?

Avantages

  1. Lisibilité : Ordre naturel gauche → droite
  2. Clarté : Chaque transformation est explicite
  3. Débogage : Facile de commenter/décommenter une étape
  4. Style : Code Elm idiomatique

Le Pattern

donnees
    |> transformation1
    |> transformation2
    |> transformation3
    |> resultat

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 ! 💪