Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Fonctions et types en Haskell

Après cette leçon: Je peux lire une petite fonction Haskell et son type.

Leçon de 55 min9 commandesLab Haskell : programmation fonctionnelle avec fonctions et types, dans le navigateur

La programmation fonctionnelle repose sur des fonctions pures

La programmation fonctionnelle écrit un programme comme un ensemble de fonctions pures : une fonction rend toujours le même résultat pour les mêmes arguments. Haskell est le langage qui pousse cette idée le plus loin, et chaque fonction y a un type.

Dans une boutique, une fonction qui retire 10 % d’un prix ne change aucun prix en cachette. Elle prend un prix et rend un autre prix. On la teste donc sans rien préparer.

À la fin de cette leçon

Remarque

Je peux lire une petite fonction Haskell et son type.

Mots-clés

MotCe que ça veut direExemple
Fonction pureune fonction dont le résultat ne dépend que de ses arguments
Effet de bordun changement hors du résultat, comme afficher ou modifier une variable
Typele genre d’une valeurInt
Signaturela ligne qui donne les types d’une fonctionsquare :: Int -> Int
Applicationdonner un argument à une fonction, sans parenthèses en Haskellsquare 12
Compositionenchaîner deux fonctions avec un point(f . g) x

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Une fonction pure ne change rien d’autre

Une fonction pure ne dépend que de ses arguments. Elle ne modifie aucune variable et n’affiche rien : elle rend une valeur.

Une action comme afficher à l’écran est un effet de bord. Haskell la sépare des fonctions pures, ce qui rend les fonctions faciles à tester et à combiner. En Haskell, on écrit square 12 pour appliquer square à 12, sans parenthèses.

Trois fonctions du fichier Basics.hs

Code: haskell
-- Basics.hs : la ligne avec :: est la signature de type.
square :: Int -> Int
square n = n * n

greet :: String -> String
greet name = "Hello, " ++ name ++ "!"

isEven :: Int -> Bool
isEven n = mod n 2 == 0

Ce que GHC écrit reste en anglais

Dans ce labo, Haskell est le compilateur GHC. Les mots qu’il écrit, comme True, False ou les messages d’erreur, restent en anglais.

La commande docker exec haskell lance GHC dans la machine du labo. runghc exécute un fichier. ghc -e calcule une seule expression, ici avec Basics.hs chargé.

Lancer le fichier Basics.hs

Commande
docker exec haskell runghc Basics.hs

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Appliquer square à 12

Commande
docker exec haskell ghc -e "square 12" Basics.hs

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Sept est-il pair ?

Commande
docker exec haskell ghc -e "isEven 7" Basics.hs

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une signature donne les types d’une fonction

Une signature s’écrit avec ::, qui se lit « a pour type ». Les types des arguments et du résultat sont séparés par des flèches.

square :: Int -> Int se lit : square prend un entier et rend un entier. Le dernier type de la ligne est toujours le résultat. GHC vérifie les types avant d’exécuter quoi que ce soit.

Exemple travaillé : lire une signature

SignatureElle se litUn appel
square :: Int -> IntPrend un entier, rend un entiersquare 12
isEven :: Int -> BoolPrend un entier, rend vrai ou fauxisEven 7
greet :: String -> StringPrend un texte, rend un textegreet "Marie"
map :: (a -> b) -> [a] -> [b]Prend une fonction et une liste, rend une listemap (+ 1) [10, 20]

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Le type de square

Commande
docker exec haskell ghc -e ":t square" Basics.hs

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Le type de map

Commande
docker exec haskell ghc -e ":t map"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Saluer Marie

Commande
docker exec haskell ghc -e 'greet "Marie"' Basics.hs

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une faute de type, première ligne

Commande
docker exec haskell ghc -e '1 + "a"' 2>&1 | head -n 1

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

La composition enchaîne deux fonctions

Le point . compose deux fonctions : (f . g) x veut dire f (g x). D’abord g travaille, puis f reçoit son résultat.

Pour que cela marche, le résultat de g doit avoir le type que f attend. Le type de . le dit : il prend deux fonctions et en rend une troisième.

Exemple travaillé : (length . show) 12345

ÉtapeFonctionCe qu’elle reçoitCe qu’elle rend
1show12345, un nombre"12345", un texte
2length"12345"5, la longueur du texte

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Composer length et show

Commande
docker exec haskell ghc -e "(length . show) 12345"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Le type du point

Commande
docker exec haskell ghc -e ":t (.)"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Erreur fréquente

Attention

Beaucoup de gens pensent que n = n + 1 ajoute un à n, comme en Python. En Haskell, = veut dire « est défini comme » : un nom garde sa valeur pour toujours. Cette ligne dirait que n est égal à n plus un, ce qui n’a pas de sens.

Pour aller plus loin

Dans le labo, ouvrez le terminal et tapez docker exec -it haskell ghci Basics.hs. Le prompt de GHC attend vos expressions : tapez square 9, puis :t greet.

Quittez avec :quit. Ajoutez ensuite à une copie du fichier une fonction triple :: Int -> Int et appelez-la.

À propos de ce labo et de sa source: Lab Haskell : programmation fonctionnelle avec fonctions et types, dans le navigateur

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.