Programmation fonctionnelle

Table of Contents

1. Introduction

1.1. Effets de bords

Le soucis des fonctions du paradigme impératif, c'est qu'on peut avoir des changements des paramètre dans d'autres fonctions. C'est ce que les fonctions pures règlent : la fonction renvoie toujours le même résultat. Haskell est un langage fonctionnel pur, càd qu'il n'a que des fonctions pures. C'est un langage strict (bonne nouvelle !). Il faut un peu se battre avec le compilateur, mais il est un bon garde-fous : si le code compile, alors il y a de fortes chances que le code soit correct.

2. Haskell

2.1. Les expressions

prenons la fonction polynôme \(f(x) = ax^{2}+bx+c\)

En python, on l'écrirait :

def poly(a, b, c, x):
    x1 = a*x*x
    x2 = b*x
    return x1 + x2 + c

En haskell, c'est :

poly a b c x = a*x*x + b*x + c

Il n'y a aucune instruction, que des expressions.

Opérateur de typage : `::`. Par exemple :

(3+6)::Float

Et interdiction de faire `(3::Float) + (5::Int)`, c'est vraiment pas bien et le compilateur sera bougon.

2.2. Les fonctions

La fonction `doubler`

doubler :: Integer -> Integer -- Typage de doubler
doubler x = 2*x -- Définition de doubler

La fonction `estMajuscule`

estMajuscule :: Char -> Bool
estMajuscule c = 'A' <= c && c <= 'Z'

2.3. Sous expression, sous fonctions

2.3.1. Déclaration where

<expr>
  where
    <decl1>
    <decl2>
    ...

2.3.2. Expression let in

let
    <decl1>
    <decl2>
in <expr>

2.3.3. Exemple : différence de gaussiennes

dog :: Float -> Float -> Float -> Float -> Float
dog x y si so = g so - g si
    where
    g s = norm/s*exp (coords/s)
    norm = 1 / (2*pi)
    pi = 3.14159
    coords = x*x + y*y

2.4. Opérateurs binaires

test :: Integer -> Integer -> (Integer -> Integer -> Integer) -> Integer
test a b f = f a b

test 3 5 + -- 8
test 3 5 * -- 15

Pour définir des opérateurs infixes, on écrit :

(+*) :: Int -> Int -> Int
(+*) a b = 2* (a+b)

1 +* 2

doubleSomme :: Int -> Int -> Int
a `doubleSomme` b = 2* (a+b)

doubleSomme 2 3
2 `doubleSomme` 3

2.5. Équivalent des structures de contrôle

2.5.1. Conditionnelle

En python :

def va(x):
    res = x
    if x < 0:
        res = -x
    return res

En Haskell

va :: Int -> Int
va a -> if a < 0 then -a else a

2.5.2. Gardes

func a1 a2 ... an
  | <cond1> = <expr1>
  | <cond2> = <expr2>
  | otherwise = <exprDefault>

2.6. Types composés

2.6.1. Tuples

Type (Int, Int) : (1, 1), (4, 2)

Cas particulier ! Type `Unit`

sertARien :: Int -> ()
sertARien a = ()

2.6.2. Listes

Type [Float], Type[(Int, Char)]...

Fonctions `null` (vacuité), `head` `tail`, mais peu utilisées

2.7. Filtrage de motif

Exemple :

incrementTuple :: (Bool, Int, Int) -> (Bool, Int, Int)
incrementTuple t = ... ?  -- Comment faire des opérations en fonction du bool ?

-- On fait :

incrementTuple t = case t of
  (True, n1, n2) -> (True, n1, n1+n2)
  (False, n1, n2) -> (False, n2, n1)

Author: romann

Created: 2026-09-03 jeu. 00:56

Validate